BindToController behavior in content area versus sandbox

I played with the bindToController option for directives. I stumbled upon the seemingly strange difference between behavior using a child’s area compared to an isolated area. When I use an isolated area, a new area is created for the directive, but changes to the attributes of the associated controller are redirected to the parent area. However, when I use the child scope, my example is interrupted. (Using bindToController using child areas should be allowed according to http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html#improvements-in-14 )

Code:

 { restrict: 'E', scope: {}, controller: 'FooDirCtrl', controllerAs: 'vm', bindToController: { name: '=' }, template: '<div><input ng-model="vm.name"></div>' }; 

Working demo https://jsfiddle.net/tthtznn2/

Version using the children's area:

 { restrict: 'E', scope: true, controller: 'FooDirCtrl', controllerAs: 'vm', bindToController: { name: '=' }, template: '<div><input ng-model="vm.name"></div>' }; 

Demo: http://jsfiddle.net/ydLd1e00/

Name changes are pushed to the child pane, but not to the parent pane. This is in contrast to binding to isolated space. Why is this?

+5
source share
1 answer

This is because you use the same alias for both controllers (and has nothing to do with the vs string object value, as indicated in the comments).

As you know, the syntax of controller as alias simply creates the alias property in scope and sets it to the controller instance. Since you use vm as an alias in both cases ( MainCtrl and FooDirCtrl ), you "obscure" the MainCtrl alias in the case of a normal child region. (In this context, “normal” means “prototype inheritance from the parent realm.”) Thus, when you try to evaluate vm.name ( vm for MainCtrl ) in the new realm to get the “parent value”, it actually evaluates FooDirCtrl.name ( which is undefined), and this happens when you try to assign the parent scope back.

In the version of the region, the selection is not affected, since the region does not inherit the parent region from it.

Updated fiddle


UPDATE: We ’ll take a closer look at the source code, this may be a mistake (since bindToController support in non-isolated areas was added "retroactively"). We seem to have gone away with this error due to prototypal inheritance, but when the names collide, we are out of luck.

I need to take a closer look to make sure that this is really a mistake, and if it is "fixed", but for now you can get around it using different aliases for your controllers (see the fiddle above).


This (part) is why I don’t like using vm as my alias (I don’t know how popular stylists suggest it) :)

Note this in angular.js # 13021 .

+3
source

Source: https://habr.com/ru/post/1233058/


All Articles