//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的詳細圖文解說