Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together.
The ngInit directive allows you to evaluate an expression in the current scope. This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit : aliasing special properties of ngRepeat , as seen in the demo below.
AngularJS provides reusable components. Q 14 - Which of the following is not a core AngularJS directive.
First, the right place to mess with rendering are directives. My advice would be to wrap DOM manipulating jQuery plugins by directives like this one.
I had the same problem and came up with this snippet. It uses $watch
and $evalAsync
to ensure your code runs after directives like ng-repeat
have been resolved and templates like {{ value }}
got rendered.
app.directive('name', function() {
return {
link: function($scope, element, attrs) {
// Trigger when number of children changes,
// including by directives like ng-repeat
var watch = $scope.$watch(function() {
return element.children().length;
}, function() {
// Wait for templates to render
$scope.$evalAsync(function() {
// Finally, directives are evaluated
// and templates are renderer here
var children = element.children();
console.log(children);
});
});
},
};
});
Hope this can help you prevent some struggle.
This post is old, but I change your code to:
scope.$watch("assignments", function (value) {//I change here
var val = value || null;
if (val)
element.dataTable({"bDestroy": true});
});
}
see jsfiddle.
I hope it helps you
Following Misko's advice, if you want async operation, then instead of $timeout() (which doesn't work)
$timeout(function () { $scope.assignmentsLoaded(data); }, 1000);
use $evalAsync() (which does work)
$scope.$evalAsync(function() { $scope.assignmentsLoaded(data); } );
Fiddle. I also added a "remove row of data" link that will modify $scope.assignments, simulating a change to the data/model -- to show that changing the data works.
The Runtime section of the Conceptual Overview page explains that evalAsync should be used when you need something to occur outside the current stack frame, but before the browser renders. (Guessing here... "current stack frame" probably includes Angular DOM updates.) Use $timeout if you need something to occur after the browser renders.
However, as you already found out, I don't think there is any need for async operation here.
I have found the simplest (cheap and cheerful) solution is simply add an empty span with ng-show = "someFunctionThatAlwaysReturnsZeroOrNothing()" to the end of the last element rendered. This function will be run when to check if the span element should be displayed. Execute any other code in this function.
I realize this is not the most elegant way to do things, however, it works for me...
I had a similar situation, though slightly reversed where I needed to remove a loading indicator when an animation began, on mobile devices angular was initializing much faster than the animation to be displayed, and using an ng-cloak was insufficient as the loading indicator was removed well before any real data was displayed. In this case I just added the my return 0 function to the first rendered element, and in that function flipped the var that hides the loading indicator. (of course I added an ng-hide to the loading indicator triggered by this function.
I think you are looking for $evalAsync http://docs.angularjs.org/api/ng.$rootScope.Scope#$evalAsync
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With