Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
fix(ngInit): evaluate ngInit before ngInclude
Browse files Browse the repository at this point in the history
The priority of ngInit is adjusted to occur before ngInclude, and after
ngController. This enables ngInit to initiallize values in a controller's
scope, and also to initiallize values before ngInclude executes.

Closes #5167
Closes #5208
  • Loading branch information
Caitlin Potter authored and IgorMinar committed Dec 5, 2013
1 parent 21e48ab commit 0e50810
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/ng/directive/ngInit.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
* to initialize values on a scope.
* </div>
*
* @priority 450
*
* @element ANY
* @param {expression} ngInit {@link guide/expression Expression} to eval.
*
Expand Down Expand Up @@ -47,6 +49,7 @@
</doc:example>
*/
var ngInitDirective = ngDirective({
priority: 450,
compile: function() {
return {
pre: function(scope, element, attrs) {
Expand Down
26 changes: 26 additions & 0 deletions test/ng/directive/ngInitSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,30 @@ describe('ngInit', function() {
element = $compile('<div ng-init="a=123"></div>')($rootScope);
expect($rootScope.a).toEqual(123);
}));


it("should be evaluated before ngInclude", inject(function($rootScope, $templateCache, $compile) {
$templateCache.put('template1.tpl', '<span>1</span>');
$templateCache.put('template2.tpl', '<span>2</span>');
$rootScope.template = 'template1.tpl';
element = $compile('<div><div ng-include="template" ' +
'ng-init="template=\'template2.tpl\'"></div></div>')($rootScope);
$rootScope.$digest();
expect($rootScope.template).toEqual('template2.tpl');
expect(element.find('span').text()).toEqual('2');
}));


it("should be evaluated after ngController", function() {
module(function($controllerProvider) {
$controllerProvider.register('TestCtrl', function($scope) {});
});
inject(function($rootScope, $compile) {
element = $compile('<div><div ng-controller="TestCtrl" ' +
'ng-init="test=123"></div></div>')($rootScope);
$rootScope.$digest();
expect($rootScope.test).toBeUndefined();
expect(element.children('div').scope().test).toEqual(123);
});
});
});

4 comments on commit 0e50810

@SchizoDuckie
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not completely sure this has fixed everything.

I've had to move the ng-init parameter outside of the ng-controller, otherwise the value would stay on undefined. (angular 1.2.5)

Works:

<div ng-init="resourcesUrl = 'planning_planboard_resources'">
   <div ng-controller="ResourcePlanBoard" >
      <div ng-include="'/bundles/mybundle/views/plan-board/resource-grid.html'"></div>
    </div>
</div>

Fails:

<div ng-controller="ResourcePlanBoard" ng-init="resourcesUrl = 'planning_planboard_resources'">
   <div ng-include="'/bundles/mybundle/views/plan-board/resource-grid.html'"></div>
</div>

@caitp
Copy link
Contributor

@caitp caitp commented on 0e50810 Dec 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SchizoDuckie could you reproduce that in a plnkr? It's not totally clear to me what/why that is failing (not had coffee yet)... looks unrelated to the ng-include + ng-init feature, and more just regarding ng-init + ng-controller (which should still work)

@caitp
Copy link
Contributor

@caitp caitp commented on 0e50810 Dec 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't totally tell what you're doing, but I assume it's something like this: http://plnkr.co/edit/ko8H8BmQjf5TVmDOAjWt?p=preview

If you're expecting the init value to be available immediately when the controller is invoked, unfortunately it isn't (changing that would require hacking compile.js so that init could run as soon as the scope is created, before the controller is invoked --- If we want to add that, that's really a separate bug).

Anyways, I hope that clears things up a bit

@SchizoDuckie
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @caitp I guess that's exactly what we're doing here.

Please sign in to comment.