2025-03-24

1、數據->模板

數據到表現的綁定,主要是使用模板標記直接完成的:

<p>{{ w }} x{{ h }}</p>

使用 {{ }}這個標記,就可以直接引用,並綁定一個作用域內的變量。在實現上, ng 自動創建瞭一個 watcher。效果就是,不管因為什麼,如果作用域的變量發生瞭改變,我們隨時可以讓相應的頁面表現也隨之改變。我們可以看一個更純粹的例子:

<p id="test" ng-controller="TestCtrl">{{ a }}</p>

<script type="text/javascript">

angular.module('app', [],angular.noop)

.controller('TestCtrl', function($scope){

    $scope.a = '123';

});

angular.bootstrap(document.documentElement,['app']);

</script>

上面的例子在頁面載入之後,我們可以在頁面上看到 123。這時,我們可以打開一個終端控制器,輸入:

$('#test').scope().a= '12345';

$('#test').scope().$digest();

上面的代碼執行之後,就可以看到頁面變化瞭。

對於使用 ng進行的事件綁定,在處理函數中就不需要去關心 $digest() 的調用瞭。因為 ng 會自己處理。源碼中,對於 ng 的事件綁定,真正的處理函數不是指定名字的函數,而是經過 $apply() 包裝過的一個函數。這個 $apply()做的一件事,就是調用根作用域 $rootScope 的 $digest() ,這樣整個世界就清凈瞭:

<p id="test" ng-controller="TestCtrl"ng-click="click()">{{ a }}</p>

<script type="text/javascript">

angular.module('app', [],angular.noop)

.controller('TestCtrl', function($scope){

    $scope.a = '123';

    $scope.click = function(){

      $scope.a = '456';

    }

});

angular.bootstrap(document.documentElement,['app']);

</script>

那個 click 函數的定義,綁定時變成瞭類似於:

function(){

  $scope.$apply(

    function(){

      $scope.click();

    }

  )

}

這裡的 $scope.$apply()中做的一件事:

$rootScope.$digest();

2. 模板->數據

模板到數據的綁定,主要是通過 ng-model 來完成的:

<input type="text" id="test" ng-controller="TestCtrl"ng-model="a"/>

<script type="text/javascript">

angular.module('app', [],angular.noop)

.controller('TestCtrl', function($scope){

    $scope.a = '123';

});

angular.bootstrap(document.documentElement,['app']);

</script>

這時修改 input 中的值,然後再在控制終端中使用:

$('#test').scope().a

查看,發現變量 a 的值已經更改瞭。

實際上, ng-model是把兩個方向的綁定都做瞭。它不光顯示出變量的值,也把顯示上的數值變化反映給瞭變量。這個在實現上就簡單多瞭,隻是綁定 change事件,然後做一些賦值操作即可。不過 ng 裡,還要區分對待不同的控件。

3. 數據->模板->數據->模板

現在要考慮的是一種在現實中很普遍的一個需求。比如就是我們可以輸入數值,來控制一個矩形的長度。在這裡,數據與表現的關系是:

長度數值保存在變量中

變量顯示於某個 input 中

變量的值即是矩形的長度

input 中的值變化時,變量也要變化

input 中的值變化時,矩形的長度也要變化

當然,要實現目的在這裡可能就不止一種方案瞭。按照以前的做法,很自然地會想法,綁定input 的 change事件,然後去做一些事就好瞭。但是,我們前面提到過 ng-model 這個東西,利用它就可以在不手工處理 change 的條件下完成數據的展現需求,在此基礎之上,我們還需要做的一點,就是把變化後的數據應用到矩形的長度之上。

最開始,我們面對的應該是這樣一個東西:

<p ng-controller="TestCtrl">

  <p style="width: 100px; height: 10px; background-color:red"></p>

  <input type="text" name="width" ng-model="width" />

</p>

<script type="text/javascript">

angular.module('app', [],angular.noop)

.controller('TestCtrl', function($scope){

    $scope.width = 100;

});

angular.bootstrap(document.documentElement,['app']);

</script>

我們從響應數據變化,但又不使用 change事件的角度來看,可以這樣處理寬度變化:

angular.module('app',[], angular.noop)

.controller('TestCtrl',function($scope){

  $scope.width = 100;

  $scope.$watch('width',

    function(to, from){

      $element.children(':first').width(to);

    }

  );

});

使用 $watch() 來綁定數據變化。

當然,這種樣式的問題,有更直接有效的手段, ng 的數據綁定總是讓人驚異:

<p ng-controller="TestCtrl">

  <p style="width: 10px; height: 10px; background-color:red" ng-style="style">

  </p>

  <input type="text" name="width" ng-model="style.width" />

</p>

<script type="text/javascript">

angular.module('app', [],angular.noop)

.controller('TestCtrl', function($scope){

    $scope.style = {width: 100 + 'px'};

});

angular.bootstrap(document.documentElement,['app']);

</script>

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *