Conditional ng-include together with ng-controller in AngularJS - angularjs

I have a conditional ng-include directive with a ng-controller associated, but it seems the controller isn't run when the condition is true.
The target is to include the template only when the condition is met and avoid the TypeError: Cannot call method 'insertBefore' of null issue.
For example:
<div ng-include src="myContent.imgList ? 'ui/image-list.html' : null" ng-controller="ImgListSubCtrl">
</div>
When myContent.imgList is filled with data, I expect the image-list.html template to be appended to the DOM and ImgListSubCtrl to be run, but it isn't.
Is this the expected behavior?. I'm using Ionic Framework with Angular 1.2.17.
Thank you.

I already found an explanation, though further comments are welcome.
The following Codepen shows the mentioned behavior and the solution (in Ionic Framework 1.0.0-beta12): http://codepen.io/anon/pen/FnojD?editors=101
The first include doesn't display any count, though the second one displays it correctly.
It seems that when using ng-include along with ng-controller, the controller is only run once, even when the ng-include src expression evaluates to null.
To run it when the template is actually included (when ng-include src isn't null), a solution is to avoid the conditional ng-include and wrap it in a ng-if block, so the whole element is re-created dynamically, as shown in the Codepen above.
In the example from the question:
<div ng-if="myContent.imgList">
<div ng-include src="'ui/image-list.html'" ng-controller="ImgListSubCtrl">
</div>
</div>
I hope it helps.

Related

ng-if doesn't prevent URLs in inner HTML from being evaluated

I have some HTML that is conditionalized with the ng-if tag.
<div ng-if="localVideoExists">
<video id="videoPlayer" controls src='{{localVideoSrc}}' style="max-height: 400px;" />
</div>
At no time does the condition in the ng-if directive evaluate as true. I would think that this means the inner HTML would never be added to the DOM. However, my web server logs show many requests in the form
/{{localVideoSrc}}
So, something is causing the video tag to pop into existence (although I never find it in the DOM) and it is creating a web request based on the not-yet-evaluated Angular template string {{localVideoSrc}}. I cannot seem to prevent this behavior. In fact, the first line in my controller is:
$scope.localVideoExists = false;
I've also disabled any functionality for now, that would ever set localVideoExists to true.
Any insight would be appreciated!
The reason of that is that Angular loads after the DOM has loaded. So the HTML is parsed and executed before Angular is activated. So, the browser loads the HTML inside the ng-if body and makes a request for the {{localVideoSrc}}.
To prevent this kind of behavior, use ng-src: https://docs.angularjs.org/api/ng/directive/ngSrc
Probably, you also need to use the $sce service because of security.
Use ng-src instead src
<div ng-if="localVideoExists">
<video id="videoPlayer" controls ng-src='{{localVideoSrc}}' style="max-height: 400px;" />
</div>
please see more here https://docs.angularjs.org/api/ng/directive/ngSrc

AngularJS + Twitter Popover: Content Iteration

I'm using twitter bootstrap with a popover and got a AngularJS scoped variable to appear correctly. The below works.
(data-content="{{notifications[0].user}} shared {{notifications[0].user_two}}'s records")
When I add the following
(data-content="<b>{{notifications[0].user}} shared {{notifications[0].user_two}}'s records</b>")
No errors show up, but all of the {{}} no longer render.
So I tried this as a test of sorts
(data-content="<div ng-repeat='item in notifications'>test {{item}} <br/><hr/></div>")
Much like the last example, I see the "test" but not the {{item}}. And the "test" only show s up once, even though the notifications had three elements. When I look at the DOM there's this
<div class="popover-content">
<div ng-repeat="item in notifications">you <br><hr></div>
</div>
I've also tried just creating a directive to iterate through the array and make the output I want, but my attempt to set data-content equal to a directive have been failures. The examples I've found elsewhere I'm confident would work, but I just wanted to confirm before I begin implementing something like this (http://tech.pro/tutorial/1360/bootstrap-popover-using-angularjs-compile-service) or (Html file as content in Bootstrap popover in AngularJS directive) that I'm not missing a straightforward fix to the problem I outlined above that would not require me creating a directive.
Edit:
Plunkr Url http://plnkr.co/edit/VZwax4X6WUxSpUTYUqIA?p=preview
html might be breaking it, try marking it as trusted html using $sce
How do you use $sce.trustAsHtml(string) to replicate ng-bind-html-unsafe in Angular 1.2+
$scope.html = '<ul><li>render me please</li></ul>';
$scope.trustedHtml = $sce.trustAsHtml($scope.html);
<button ... data-content="trustedHtml" ...> </button>

Can I have nested ng-include's?

I have a template that is inserted via ng-include and that template also has an ng-include. The inner ng-incude is not being shown. Why?
Main Template:
<div ng-include src="'views/outer.html'"></div>
views/outer.html:
<div ng-repeat="item in items">
// Stuff
<div ng-include src="'views/inner.html'"></div> // not being shown
// More stuff
</div>
The code you posted should work so the problem is probably situated somewhere else.
One of the reasons could be that a JavaScript error is thrown somewhere else or that no items are found in the scope. Make sure to check the browser console.
Here is a working version of your code for your convenience:
http://plnkr.co/edit/pCTInrtITqHraC1hPyZH?p=preview
Hope that helps!
ng-include is a directive. Your view/outer.html should do like this:
$parent.items
Because directive not inherit parent automatically.

AngularJS Animations ng-switch ng-repeat

I am trying to do what looks like a simple process: to display a list of items received from an HTTP request with animation.
First of all, here is my way of doing it ( I am open to any suggestions to do it in a better angular way ):
I define a scope variable state that I initialize to loading in my controller and that I change to loaded when I receive data from the HTTP request.
I initialize a scope variable items with the received data.
In my view, I use ng-switch for the states, and ng-repeat with the items.
I define an animation with css on ng-repeat.
Here is a plunkr ( with a $timeout instead of the request ).
I cannot understand why the animation does not work.
Any help will be appreciated. Thanks.
The reason it is happening is because your ng-when. The same thing happens with ng-if, but would work fine if you used ng-show.
The problem is that when your ng-when condition returns true, the ng-when first renders it's content in a detatched dom (so animations do not happen). This dom is then attached to the dom tree (this step is animated but you would have to put your animation class on the ng-when).
When using something like ng-show or ng-hide things work as expected because the dom is always attached (it is simply shown/hidden).
This might be considered either a bug or a limitation of ng-animate, you might want to post a github issue and see if the angular guys have any thoughts.
It seems to be a "feature" of angular that it won't add .ng-enter to repeat items inside ng-switch-when block. You can remove ng-switch-when="loaded" and it will work (You don't really need it as ng-repeat won't do anything if there is no items)
<div ng-switch="state">
<div ng-switch-when="loading">
<p>Please wait...</p>
</div>
<div >
<ul ng-repeat="item in items" class="animate-items">
<li>{{item}}</li>
</ul>
</div>
</div>
http://plnkr.co/edit/ocEj7BSQPSeIdnnfAOIE?p=preview

Does ngIf accept boolean parameter?

I have the following
<div ng-if="false"> nothing here </div>
Shouldn't the div's content be hidden?
I want to make this slightly more complex like :
<div ng-if="user.id == 1">
The name is: {{user.name}}
</div>
but none of the above work.
The aim is if the ng-if expression is true to run the code inside the div. Is the ngIf the correct expression or is there a better boolean/expression handler?
ng-if directive is introduced in AngularJS v1.1.5, so you must be using some older version of Angular.
Here is a plunker: http://plnkr.co/edit/gvDUsLrTSS54jCJMDS89?p=preview
Everything just works fine.
Stewie is right you are using probably the stable 1.0.8 version of angular.

Resources