How do I dynamically load multiple templates using AngularJS? - angularjs

I'm new to AngularJS, coming from a PHP background where I do all the template aggregation on the server. With PHP I would grab several templates, mash them together, then send it to the clients browser. AngularJS allows me to insert a template using ng-view. This is great, but it doesn't handle the case where the template that I insert may include tags that are placeholders for other templates. For example, I may have the following as one of my templates:
<div class="some_class">
<div class="another_class">
{content}
</div>
</div>
In PHP I would insert this template, then replace the contents of {content} with another template. In AngularJS I know how to insert the main template (using ng-view), but I'm not sure how to dynamically load my "partial template" into the {content} tag. How is this suppose to be done with AngularJS?

A straightforward approach would be to use the ngInclude directive:
<div class="some_class">
<div class="another_class">
<ng-include src="templatePath"></ng-include>
</div>
</div>
Then, in Controller that is associated with this template you can define the templatePath variable dynamically:
function MyCtrl($scope){
$scope.templatePath = // define this var dynamically here
}

Using ng-view to nest multiple templates is not currently supported natively in Angular.js. There are, however, multiple options to emulate that functionality. See the answers in this SO question for several of those options, including the ui-router suggested by akonsu.

Related

Preload nested ng-includes

I'm using AngularJS to "include" html partials in my web app. I'm using a nested ng-include for this.
I also have an animation on the outer most ng-include. It all works fine. The only problem is that the outer ng-include template is loaded first. Then the included HTML file also has an ng-include which also loads an HTML file.
The last included HTML file causes the div to suddenly expand in size and that makes the animation look jumpy and weird.
This problem could be solved if all the nested ng-includes could be preloaded somehow. Is something like that possible in AngularJS?
The code I have looks something like this:
My main view:
<div class="animation-grow-in animation-grow-out" ng-repeat="myList">
<div ng-include"base-partial.html"></div>
</div>
The base-partial.html file:
<div ng-switch="myList.type">
<div ng-switch-when="file1">
<div ng-include="'file1.html'"></div>
</div>
<div ng-switch-when="file2">
<div ng-include="'file2.html'"></div>
</div>
</div>
The file1.html and file2.html contain forms.
But because filex.html is loaded with a delay that makes it all look jumpy. So is there a solution for this problem? Can I preload all nested ng-includes?
You can use angularjs template caching service to cache your template. When boot strapping your application, put all your templates inside a cache so that it will not make XHR calls for your templates.
https://docs.angularjs.org/api/ng/service/$templateCache

AngularJS insert invalid HTML

I have an app that requires HTML to be pieced together from different APIs. Rather than getting into specifics there, let me just say that we have tried getting away from that many times but in the end the best answer always end up being what we currently have. Hopefully that changes someday but for now it's working great.
Currently, the HTML is parsed together as a string server-side using NodeJS and sent across the wire as complete HTML to be rendered. I'm in the process of adopting AngularJS, and while I'm loving it I am stuck on this issue-- how can I use Angular templating to insert invalid HTML at times?
The server will return three JSON fields: leadingHTML, trailingHTML, and copy. The copy field is always valid HTML, but leadingHTML and trailingHTML can sometimes return invalid HTML. When all three are added together, valid HTML results.
Let me illustrate:
leadingHTML='<figure>';
copy = '<img src="img1.jpg"/><img src="im2.jpg"/><figcaption>I love AngularJS</figcaption>';
trailingHTML='</figure>';
As you can see, if you add those together you will get the valid HTML that is required to be displayed. It's pretty easy to make the fields trustworthy HTML in Angular:
for (i in data.results){
data.results[i].copy=$sce.trustAsHtml(data.results[i].copy);
data.results[i].leadingHTML =$sce.trustAsHtml(data.results[i].leadingHTML );
data.results[i].trailingHTML =$sce.trustAsHtml(data.results[i].trailingHTML );
}
And then render the copy in my view:
<div ng-repeat='i in data.result'>
<p ng-bind-html='i.copy'></p>
</div>
But I need a way that does what this looks like it would do, but the leadingHTML and trailingHTML scope variables get render as strings:
<div ng-repeat='i in data.result'>
{{ i.leadingHTML }}
<p ng-bind-html='i.copy'></p>
{{ i.trailingHTML }}
</div>
Is the best answer here to build the template via javascript? Would that even work?
Are you able to pre-process your data so that you do have valid HTML?
var item;
for (i in data.results){
item = data.results[i];
item.content = $sce.trustAsHtml(item.leadingHTML + item.copy + item.trailingHTML);
}
Then you can just bind to the combined content in the view:
<div ng-repeat='i in data.results'>
<div ng-bind-html='i.content'></div>
</div>
Edit:
Yes, this will allow you to embed expressions in your HTML content.
In fact, you will need to be careful that you aren't opening yourself up to security exploits in the trusted HTML content (see the example at the bottom of the page for the $sce service).
Using $sce.trustAsHtml in this way is roughly equivalent to loading a directive's templateUrl from your site, so the security considerations around that are probably the same. See the "How does it work?" and
"Impact on loading templates".

Using angular-directives within JSF

I am trying to use angular together with an JSF backend.
I have the problem that custom directives are not processed within JSF when set as attributes for example:
<div my-directive .... > ...(some code)... </div>
JSF or XHTML sais that is not allowed to use attributes withtout being assigned (with an =).
To workaround, I used
<div my-directive ="" ...> ...(some code)... </div>
That would be fine with angularFS but when using the attribute
"my-directive" it will be removed after JSF rendering completely. The problem is my html relies on JSF ajax calls to a DB that I need as the backend relies on JSF 2.2/JSP.
The only thing I can bring it to work is using a tag/an element like
<my-directive> ... </my-directive>
Doing so is somewhat undesireable as I would like to use an attribute.
I learnt that JSF can be tricky if used with angularFS.
Did someone have this issue before?
If I understood your question correctly, JSF2.2 does what you need. It allows either to go with pure Html5 and bind with JSF or go with JSF and use p:passthrough.
#see a few links below
Link 1, Link 2, Link 3

Difference between header-bar and class=bar-header

There are two ways in which one can make headers using Ionic framework.
<div class="bar bar-header bar-dark">
<h1 class="title">Title</h1>
</div>
And
<header-bar title="'Title'" type="bar-dark">
</header-bar>
Links in Documentation :
For first : http://ionicframework.com/docs/components/
For second : http://ionicframework.com/docs/angularjs/views/header/
What is the difference between them?
The first is native HTML elements using the predefined CSS class names.
The second is using an AngularJS directive. Basically it is a custom element that at runtime will be replaced by a template. See here for the actual AngularJS directive definition. You can see the template that replaces the original element.
Directives like this will play an interesting part of the future of the web. There is a standard on its way in Web Components that will standardize these kind of markup constructs. Besides directives in AngularJS there is another popular way of doing this style of components using Polymer.

angular js reloading view

I'm using Angular JS and Angular IU-Router in my project and using a lot of ui-views. I have a situation where I need to change the language of the site, therefore I need to swap my ui-view's model to another model with the relevant language. I already have a service that detects the relevant model and passes it into the ui-view's controller. So if I can reload the ui-view, then in theory my problem would be solved.
I recall reading something about automatically reloading a ui-view (or possibly an ng-view) and re-instantiating its controller, but after much searching I haven't been able to find that information again.
Does anyone know what it is I'm looking for?
1 Take a look at angular-translate
https://github.com/PascalPrecht/angular-translate
2 In your case, add some if-else control ( ng-if, ng-switch etc. ) in the outer div, use the same subview in the inner div. Then change the settings.currentLang when the language changes may cause the subview reload (not tested).
<div ng-controller="containerCtrl">
<div ng-if="settings.currentLang=='en'">
<div ui-view='subview'></div>
</div>
<div ng-if="settings.currentLang=='ja'">
<div ui-view='subview'></div>
</div>
</div>

Resources