//app.js angular.module('deapp', []) .controller('ParentCtrl', ['$scope', ParentCtrl]) .controller('ChildCtrl', ['$scope', ChildCtrl]); function ParentCtrl($scope) { $scope.description = ''; } function ChildCtrl($scope) { } //index.html <div data-ng-controller="ParentCtrl"> <div data-ng-controller="ChildCtrl"> <textarea class="description" data-ng-model="description"></textarea> </div> </div>
我修改textarea的内容时,绑定的description彻底没更新,只能用chrome插件ng-inspector看一下。html
图1 初始scopeangularjs
图2 输入后ChildCtrl 出现descriptionchrome
因此能够看到问题变成了Angular Scope Inheritanceapp
我用word文档画了scope的继承图示,以下spa
图3 初始scope插件
图 4 错误的给ChildCtrl添加了descriptioncode
在这个图能够看到实际上并无更新父级scope的description,反而在当前所在的ChildCtrl scope新建了description。也就是说与textarea绑定的model其实是ChildCtrl scope中的description。orm
$scope的继承是原型链继承,有两个特色:htm
读子类的属性时,子类有这个属性(hasOwnProperty)的时候则读子类本身的,子类没有的时候读父类的,无论子类有没有这个属性,在子类上都不会有新属性被建立。对象
写子类的属性时,若是子类有这个属性(hasOwnProperty)则写子类的,子类没有的话就会在子类上新建一个同名的新属性,而父类继承过来的属性被隐藏。
————来自http://pinkyjie.com/2015/02/07/prototypal-inheritance-of-scope-in-angularjs/
因此对于description也是同样,读description时,先在ChildCtrl中读,读不到就到ParentCtrl中读,因此事先给ParentCtrl的description设置的初始值,在页面刷新后是能够显示出来的。
可是,写description的时候就不同了,在ChildCtrl中找不到就直接建立一个新的属性,父级scope的同名属性就被隐藏了,textarea绑定的模型也就变成了ChildCtrl scope中的description,日后再怎么修改textarea的内容,父级scope的description永远保持原来的值。
这不是我想看到的,办法是有的,使用.就能解决这个问题了。
只需改html,将textarea显示绑定到$parent.description
<div data-ng-controller="ParentCtrl">
<form data-ng-controller="ChildCtrl"> <textarea class="description" data-ng-model="$parent.description"></textarea> </form>
</div>
使用对象的形式来绑定description
// app.js
function ParentCtrl($scope) {
$scope.info = { description: '156' };
}
function ChildCtrl($scope) {
}
// index.html
<div data-ng-controller="ParentCtrl">
<form data-ng-controller="ChildCtrl"> <textarea class="description" data-ng-model="info.description"></textarea> </form>
</div>
为何一个.就能解决问题了呢,以第二个方法为例。
写的时候是写info.description,须要先读info,ChildCtrl没有info,因而去ParentCtrl读,找到info后,就写父级scope的info.description。
Angular Scope Inheritance的详细图文解说