最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Angularjs中不同類型的雙向數(shù)據(jù)綁定

 更新時(shí)間:2018年07月16日 16:45:28   作者:running_sun  
這篇文章主要介紹了淺談Angularjs中不同類型的雙向數(shù)據(jù)綁定,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

Angularjs1.X中兩種不同的雙向數(shù)據(jù)綁定

聊聊 Angularjs1.x中那些活見鬼的事情。

一. html與Controller中的雙向數(shù)據(jù)綁定

html-Controller的雙向數(shù)據(jù)綁定,在開發(fā)中非常常見,也是Angularjs1.x的宣傳點(diǎn)之一,使用中并沒(méi)有太多問(wèn)題。

1.1數(shù)據(jù)從html流向controller

也就是從 視圖層 流向 模型層 ,原生html中需要使用表單元素(例如 input 標(biāo)簽)來(lái)收集用戶輸入信息,Angularjs中通過(guò)在表單元素上使用 ng-model 標(biāo)簽,當(dāng)用戶輸入信息時(shí),同步將用戶輸入的信息賦值給controller中的變量:

<body ng-app="myApp">
  <div id="main" ng-controller="myCtrl">
    <p>改變輸出值:</p>
    <input type="text" ng-model="testInfo.content" ng-change="showInput()">
  </div>
 <script src="./angular.min.js"></script>
 <script>
  angular.module('myApp',[])
  .controller('myCtrl',['$scope',function($scope){
    $scope.showInput = function() {
     console.log($scope.testInfo.content);
    }
  }]);
 </script>
</body>

在頁(yè)面上輸入1234567即可看到,每次在頁(yè)面輸入數(shù)字后,控制臺(tái)輸出的 $scope,testInfo.content 的值都和頁(yè)面保持一致:

1.2 數(shù)據(jù)從controller流向html

也就是從 模型層 流向 數(shù)據(jù)層 ,當(dāng)controller中的數(shù)據(jù)模型變量發(fā)生變化后,Angularjs又會(huì)根據(jù)數(shù)據(jù)模型的值去改變 ng-model 指令綁定的表單元素的值,使用 ng-bind 指令也可以被動(dòng)獲得來(lái)自controller的數(shù)據(jù)流。

我們編寫如下demo進(jìn)行測(cè)試:

<body ng-app="myApp">
  <div id="main" ng-controller="myCtrl">
    <button ng-click="add()">+1</button>
    <p>改變輸出值:</p>
    <input type="text" ng-model="testInfo.content">
    <p>使用ng-bind綁定的標(biāo)簽:</p>
    <p ng-bind="testInfo.content"></p>
  </div>
  <script src="./angular.min.js"></script>
  <script>
  angular.module('myApp', [])
    .controller('myCtrl', ['$scope', function($scope) {
      //初始化
      $scope.testInfo = {
        content: 0
      }

      $scope.add = function () {
        $scope.testInfo.content += 1;
        console.log($scope.testInfo.content);
      }
    }]);
  </script>
</body>

demo中,每次點(diǎn)擊 +1 按鈕, $scope.testInfo.content 的值會(huì)增加1,我們可以看到頁(yè)面上的結(jié)果:

1.3 你丫倒是刷視圖啊

來(lái)看看第一個(gè) 活見鬼 的例子,demo跟上面很類似,只是將 鼠標(biāo)點(diǎn)擊觸發(fā) 的方式改成了 定時(shí)器自動(dòng)觸發(fā)

<body ng-app="myApp">
  <div id="main" ng-controller="myCtrl">
    <button ng-click="add()">+1</button>
    <p>改變輸出值:</p>
    <input type="text" ng-model="testInfo.content">
    <p>使用ng-bind綁定的標(biāo)簽:</p>
    <p ng-bind="testInfo.content"></p>
  </div>
  <script src="./angular.min.js"></script>
  <script>
  angular.module('myApp', [])
    .controller('myCtrl', ['$scope', function($scope) {
      //初始化
      $scope.testInfo = {
        content: 0
      }

      //定時(shí)自增
      setInterval(function () {
       $scope.testInfo.content += 1;
       console.log('$scope.testInfo.content的值現(xiàn)在是:',$scope.testInfo.content);
      },1000)
    }]);
  </script>
</body>

你會(huì)活見鬼地發(fā)現(xiàn),數(shù)據(jù)模型一直在變,但是頁(yè)面卻沒(méi)有刷新:

這里就是 Angularjs1.X 雙向數(shù)據(jù)綁定中的第一個(gè)坑 ,你會(huì)發(fā)現(xiàn) $scope上綁定的數(shù)據(jù)模型html中顯示的內(nèi)容 有時(shí)候并不是實(shí)時(shí)關(guān)聯(lián)的。這其實(shí)和 Angularjs1.X 的執(zhí)行機(jī)制有關(guān)系。

如果我們自己來(lái)考慮,javascript中有一個(gè)變量的值發(fā)生了變化,現(xiàn)在要將這個(gè)值同步到html頁(yè)面上,需要怎么做呢?我們需要獲取到這個(gè)DOM元素,然后改變它的 innerHTML 屬性,如果是表單元素就修改 value 。其實(shí) Angularjs 也是這樣做的,只不過(guò)使用了自己的封裝的方法—— $apply() 。那么此處的問(wèn)題其實(shí)就在于,在 setInterval 的回調(diào)函數(shù)中去修改數(shù)據(jù)模型的值時(shí),沒(méi)有觸發(fā) $apply() 方法來(lái)更新視圖,而通過(guò)調(diào)用 Angularjs 封裝的 ng-* 方法(例如 ng-click 點(diǎn)擊方法)來(lái)修改視圖模型時(shí),會(huì)自動(dòng)觸發(fā) $apply() 方法,視圖也就同步刷新了。

解決方案1

使用 Angularjs 封裝過(guò)的 $interval 服務(wù)來(lái)實(shí)現(xiàn)定時(shí)任務(wù),感興趣的讀者可以自己看一下 Angularjs 源碼中 $intervalProvider 的部分,就會(huì)發(fā)現(xiàn)在方法最后的地方調(diào)用了 $rootScope.$apply() 。

解決方案2

如果依然使用javascript原生的定時(shí)方法,那么則需要在修改完視圖的數(shù)據(jù)模型后,手動(dòng)調(diào)用 $scope.$apply() 方法來(lái)將數(shù)據(jù)模型的變動(dòng)同步到html頁(yè)面中。

二. Controller與Directive中的雙向數(shù)據(jù)綁定

除了controller與html中的雙向綁定, Angularjs 中還有另一個(gè) 雙向數(shù)據(jù)綁定 ,那就是controller與directive之間的 綁定 。綁定的形式有很多種,我們先來(lái)看一下最常見的 雙向綁定 。

2.1 directive中的雙向數(shù)據(jù)綁定

在設(shè)定自定義指令的 scope 參數(shù)時(shí),將屬性的值設(shè)置為 = 就可以實(shí)現(xiàn)雙向數(shù)據(jù)綁定,這里API的解釋是:

父級(jí)controller中的指定變量會(huì)與自定義指令link函數(shù)中的變量 相互影響

下面的實(shí)例中,我們將看看controller中的數(shù)據(jù)模型 $scope.testInfo.content 的值與自定義指令中 scope.pagination 如何相互影響,是否如定義所說(shuō)這里的綁定真的是雙向的。示例界面如下(demo源碼請(qǐng)見附件 demo.html 文件):

  • 每次點(diǎn)擊 +1 按鈕, Scope.testInfo.content 的值都會(huì)增加1
  • 每次點(diǎn)擊 show $scope.testInfo ,控制臺(tái)都會(huì)打印出 $scope.testInfo 的值
  • 每次點(diǎn)擊標(biāo)簽上的數(shù)字,則會(huì)打印出自定義指令中 scope.pagination 的值,并將該值進(jìn)行自增

接下來(lái)的測(cè)試操作,我們將按照如下的流程進(jìn)行:

  1. 點(diǎn)擊5次+1按鈕,再點(diǎn)擊5次數(shù)字標(biāo)簽
  2. 點(diǎn)擊show $scope.testInfo按鈕

2.2 你丫怎么又不刷新了

隨著上一節(jié)的操作步驟,我們一起來(lái)見證 雙向數(shù)據(jù)綁定 中又一次鬧鬼事件:

點(diǎn)擊5次 +1 按鈕,再點(diǎn)擊5次數(shù)字標(biāo)簽

結(jié)果為:

我們看到,第一次點(diǎn)擊數(shù)字標(biāo)簽時(shí),控制臺(tái)打出了link函數(shù)中 scope.pagination 的值為5,這說(shuō)明 $scope.testInfo.content 的值被傳遞給了自定義指令中的 scope.pagination ,也就是說(shuō)數(shù)據(jù)從controller流向了directive 。而當(dāng)我們?cè)冱c(diǎn)擊4次數(shù)字標(biāo)簽(一共點(diǎn)了5次)后,從控制臺(tái)可以看出, scope.pagination 的值已經(jīng)成為10,而頁(yè)面上使用 ng-bind 指令獲取到的結(jié)果卻依舊是 5 。也就是說(shuō), 數(shù)據(jù)從沒(méi)有從directive流向controller 。是不是有一種被騙的感覺(jué)?別著急,接著看。

點(diǎn)擊 show $scope.testInfo 按鈕

結(jié)果為:

當(dāng)我們點(diǎn)擊 show $scope.testInfo 時(shí),控制臺(tái)打印出了$scope.testInfo.content的值為5,這下證據(jù)坐實(shí)了,明明說(shuō)好的雙向數(shù)據(jù)綁定,然而當(dāng)自定義指令中的 scope.pagination 改變時(shí), $scope.testInfo.content 并沒(méi)有跟著一起改變。 But!?。?! 我們會(huì)發(fā)現(xiàn),這個(gè) show $scope.testInfo 點(diǎn)下去以后,頁(yè)面上通過(guò) ng-bind 綁定的值卻變成了 10 。也就是說(shuō), 數(shù)據(jù)又從directive流回了controller 。

官方建議使用 $watch 方法來(lái)追蹤scope中的變量,而當(dāng)我們這樣做時(shí),會(huì)發(fā)現(xiàn) $watch 函數(shù) 僅能追蹤到那些通過(guò)修改controller中的數(shù)據(jù)模型而影響link函數(shù)中變量的行為并更新視圖 。

這里就是 Angularjs1.X 雙向數(shù)據(jù)綁定中的第二個(gè)坑,controller和directive中所謂的 雙向數(shù)據(jù)綁定 ,并不能追蹤指定變量的所有變化,而且不是同步完成的。

其實(shí)這里的問(wèn)題仍然和 Angularjs 的運(yùn)行機(jī)制有關(guān),解決方案如下:

解決方案1

使用自定義指令的 templateUrl 屬性替換當(dāng)前指令的模板,使用 ng-click 指令來(lái)綁定一個(gè)點(diǎn)擊響應(yīng)函數(shù),在響應(yīng)函數(shù)中改變 scope.piganation 的值。

解決方案2

在手動(dòng)綁定的監(jiān)聽回調(diào)中,修改自定義指令作用域內(nèi)的變量后,使用 scope.$emit( ) 方法通知其父級(jí)controller,并在controller中使用 $scope.$on( ) 方法監(jiān)聽同名事件,并修改對(duì)應(yīng)的數(shù)據(jù)模型的值。

解決方案3

每當(dāng)改變自定義指令中的變量值后,調(diào)用 scope.$apply() 方法,將directive中的變量值同步至controller的數(shù)據(jù)模型以及頁(yè)面。

三.原理和實(shí)戰(zhàn)總結(jié)

3.1 Angularjs中雙向數(shù)據(jù)綁定的基本原理

Angularjs中的雙向數(shù)據(jù)綁定,是通過(guò)一種叫做* "臟循環(huán)檢查(dirty-checking)" 的機(jī)制實(shí)現(xiàn)的。

其基本過(guò)程是這樣的,每當(dāng)我們使用 ng-modelng-bind 指令將數(shù)據(jù)模型中的某個(gè)變量值和html頁(yè)面上某個(gè)標(biāo)簽的內(nèi)容聯(lián)系起來(lái)時(shí),Angular就會(huì)把這些變量放進(jìn)一個(gè) WatchCollection 的集合中,并自動(dòng)幫我們來(lái)監(jiān)控這些變量。每當(dāng) WatchCollection 中有變量出現(xiàn)變動(dòng)時(shí),Angular就會(huì)遍歷 WatchCollection 來(lái)查看是否有其他監(jiān)控中的變量也被影響,每當(dāng)有一個(gè)變量被影響,Angular都會(huì)在遍歷后再進(jìn)行一次遍歷,直到某一次遍歷后 WatchCollection 中的變量都沒(méi)有變化,則Angular會(huì)認(rèn)為當(dāng)前的改動(dòng)已經(jīng)穩(wěn)定了,然后才會(huì)將數(shù)據(jù)模型的變化同步到DOM元素上去,也就實(shí)現(xiàn)了數(shù)據(jù)綁定。

我們可以把 WatchCollection 理解為當(dāng)前頁(yè)面的一種抽象,其中包含著頁(yè)面上所有有可能發(fā)生變化的部分。

3.2 雙向數(shù)據(jù)綁定的實(shí)踐經(jīng)驗(yàn)

想要在 Angularjs 項(xiàng)目中更加穩(wěn)定地使用雙向數(shù)據(jù)綁定,筆者的建議是:

Angularjs 項(xiàng)目中,盡可能地使用Angular告訴你的方式去編寫所希望實(shí)現(xiàn)的功能。

我們可以回顧一下上面在使用雙向數(shù)據(jù)綁定發(fā)生異常時(shí)的場(chǎng)景:

  • 使用了原生的定時(shí)器(Angular中你應(yīng)該使用 $interval , $timeout 服務(wù))
  • 用類原生方法(bind)為元素添加事件監(jiān)聽器,并在回調(diào)函數(shù)中修改了變量的值(Angular中,你應(yīng)該使用 ng-click 來(lái)實(shí)現(xiàn)點(diǎn)擊事件的監(jiān)聽)
  • ...

你會(huì)發(fā)現(xiàn),每當(dāng)自己沒(méi)有按照Angular的方式去編寫代碼,或者沒(méi)有按照一個(gè)模塊設(shè)計(jì)的初衷去使用它時(shí),就無(wú)法確切地得到期望的結(jié)果。這是很容易理解的,如果你沒(méi)有按照Angular要求的方式書寫代碼,憑什么期望它對(duì)你的代碼做出100%正確的回應(yīng)呢?至于上述兩種數(shù)據(jù)綁定中出現(xiàn)問(wèn)題的解決方案,上文已經(jīng)有所提及,此處不再贅述。

許多人都聽說(shuō)過(guò) "盡量不要在controller中操作DOM" 這句話,實(shí)際上它并不意味著你在controller中操作DOM會(huì)導(dǎo)致程序報(bào)錯(cuò),而是在說(shuō) 如果你同時(shí)使用 jQueryAngular 兩套系統(tǒng)來(lái)管理自己的代碼,但又沒(méi)有按照官方指定的方式來(lái)規(guī)避它們之間的沖突,那代碼很可能會(huì)變得不穩(wěn)定。 想想當(dāng)年 騰訊電腦管家360安全衛(wèi)士 將你的電腦卡死的場(chǎng)景,你就明白這樣做的結(jié)果了。

四. 小結(jié)——所謂高手

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Angular 開發(fā)學(xué)習(xí)之Angular CLI的安裝使用

    Angular 開發(fā)學(xué)習(xí)之Angular CLI的安裝使用

    這篇文章主要介紹了Angular 開發(fā)學(xué)習(xí)之Angular CLI的安裝使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • AngularJS 中的指令實(shí)踐開發(fā)指南(一)

    AngularJS 中的指令實(shí)踐開發(fā)指南(一)

    指令(Directives)是所有AngularJS應(yīng)用最重要的部分。盡管AngularJS已經(jīng)提供了非常豐富的指令,但還是經(jīng)常需要?jiǎng)?chuàng)建應(yīng)用特定的指令。這篇教程會(huì)為你講述如何自定義指令,以及介紹如何在實(shí)際項(xiàng)目中使用
    2016-03-03
  • 簡(jiǎn)介AngularJS中$http服務(wù)的用法

    簡(jiǎn)介AngularJS中$http服務(wù)的用法

    我們可以使用內(nèi)置的$http服務(wù)直接同外部進(jìn)行通信。$http服務(wù)只是簡(jiǎn)單的封裝了瀏覽器原生的XMLHttpRequest對(duì)象。接下來(lái)通過(guò)本文給大家簡(jiǎn)單介紹angularjs中http服務(wù)的用法,喜歡的朋友可以參考下
    2016-02-02
  • AngularJS入門教程之路由機(jī)制ngRoute實(shí)例分析

    AngularJS入門教程之路由機(jī)制ngRoute實(shí)例分析

    這篇文章主要介紹了AngularJS入門教程之路由機(jī)制ngRoute,結(jié)合實(shí)例形式分析了AngularJS路由機(jī)制的原理、ngRoute的組成、配置、參數(shù)與相關(guān)使用技巧,需要的朋友可以參考下
    2016-12-12
  • Angularjs中controller的三種寫法分享

    Angularjs中controller的三種寫法分享

    這篇文章給大家介紹了angularjs中controller的三種寫法,每種寫法都給出了示例代碼,對(duì)大家理解和學(xué)習(xí)很有幫助,有需要的朋友們可以參考借鑒。
    2016-09-09
  • AngularJS Bootstrap詳細(xì)介紹及實(shí)例代碼

    AngularJS Bootstrap詳細(xì)介紹及實(shí)例代碼

    本文主要介紹AngularJS Bootstrap,這兩對(duì)AngularJS Bootstrap的基礎(chǔ)知識(shí)做了詳細(xì)講解,并提供簡(jiǎn)單示例,有需要的小伙伴可以參考下
    2016-07-07
  • angularjs http與后臺(tái)交互的實(shí)現(xiàn)示例

    angularjs http與后臺(tái)交互的實(shí)現(xiàn)示例

    這篇文章主要介紹了angularjs http與后臺(tái)交互的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • Angular 的 Change Detection機(jī)制實(shí)現(xiàn)詳解

    Angular 的 Change Detection機(jī)制實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了Angular 的 Change Detection機(jī)制實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 理解Angular數(shù)據(jù)雙向綁定

    理解Angular數(shù)據(jù)雙向綁定

    AngularJS誕生于2009年,由Misko Hevery 等人創(chuàng)建,后為Google所收購(gòu)。這篇文章主要帶著大家理解Angular數(shù)據(jù)雙向綁定,感興趣的小伙伴們可以參考一下
    2016-01-01
  • AngularJS基礎(chǔ) ng-repeat 指令簡(jiǎn)單示例

    AngularJS基礎(chǔ) ng-repeat 指令簡(jiǎn)單示例

    本文主要講解AngularJS ng-repeat 指令,這里對(duì)ng-repeat的基礎(chǔ)資料做了整理,并附有示例代碼,有興趣的朋友可以參考下
    2016-08-08

最新評(píng)論

万山特区| 陆川县| 关岭| 土默特左旗| 鹤庆县| 翁牛特旗| 忻州市| 明光市| 西平县| 黑山县| 龙里县| 无棣县| 沧州市| 南投县| 大余县| 昆明市| 怀来县| 彭州市| 宁强县| 漯河市| 余庆县| 镇巴县| 新竹市| 安仁县| 巴中市| 专栏| 龙胜| 浪卡子县| 绍兴县| 固始县| 大方县| 登封市| 秭归县| 上蔡县| 榆社县| 宜宾县| 平乐县| 京山县| 康保县| 金堂县| 民和|