textarea的內容改變,綁定的model卻沒更新

問題描述:

//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

clipboard.png
圖1 初始scopeangularjs

clipboard.png
圖2 輸入後ChildCtrl 出現descriptionchrome

因此能夠看到問題變成了Angular Scope Inheritanceapp

Angular Scope Inheritance

我用word文檔畫了scope的繼承圖示,以下spa

clipboard.png
圖3 初始scope插件

clipboard.png
圖 4 錯誤的給ChildCtrl添加了descriptioncode

在這個圖能夠看到實際上並無更新父級scope的description,反而在當前所在的ChildCtrl scope新建了description。也就是說與textarea綁定的model其實是ChildCtrl scope中的description。orm

$scope的繼承是原型鏈繼承,有兩個特色:htm

  1. 讀子類的屬性時,子類有這個屬性(hasOwnProperty)的時候則讀子類本身的,子類沒有的時候讀父類的,無論子類有沒有這個屬性,在子類上都不會有新屬性被建立。對象

  2. 寫子類的屬性時,若是子類有這個屬性(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永遠保持原來的值。

這不是我想看到的,辦法是有的,使用.就能解決這個問題了。

  1. 只需改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>

  2. 使用對象的形式來綁定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的詳細圖文解說

相關文章
相關標籤/搜索