學習Angular中範圍需要注意的坑,angular

來源:互聯網
上載者:User

學習Angular中範圍需要注意的坑,angular

Angular範圍

在用angular搭建的網頁應用中,範圍(scope)這個概念是貫穿其中的。在angular的視圖(view)中的很多指令是會建立一個範圍的,例如 ng-app , ng-controller 等。這個範圍就是我們在寫控制器建構函式時注入的 $scope (angular1.2之前的版本),他是視圖模型(view model)中的一個概念。我們的資料模型(model)就是定義在範圍中的。

Angular範圍的坑

用過angular的人應該都會經過一個過程,就是剛開始還是小白的時候,剛看見資料雙向繫結覺得很牛逼,

Angular中範圍的坑1

管他三七二十一直接開始用,一頓綁定。綁定完之後,如果你運氣好(懂得angular範圍原理的老鳥無視),那麼雙向繫結就開始如願工作了,這時候我們也覺得自己好厲害,居然可以這麼快就實現“雙向繫結”這個才聽說不久的新功能了。

那麼為什麼上面說雙向繫結是因為運氣好才能正常工作呢?因為新手剛開始學angular的時候,無非就是看教程然後改動其中的代碼實現自己的業務需求,能剛開始就去學習官方文檔的選手就算有也是少數,所以這樣,大多數剛學習angular的朋友實際上不太瞭解其中的原理,但是覺得自己已經會用了。

好說了這麼多,那我們來看看如果一個新手剛開始給範圍中指定資料模型並且進行雙向繫結時,運氣不那麼好的情況。這種情況下,就會遇到上面說的坑,先來看看代碼

// html<div ng-controller="OuterCtrl">  <span ng-bind="a"></span>  <div ng-controller="InnerCtrl">    <span ng-bind="a"></span>    <button ng-click="a=a+1">遞增</button>  </div></div>// javascriptfunction OuterCtrl($scope) {  $scope.a = 1;}function InnerCtrl() {}

上面的代碼就是一個極其簡單的雙向繫結的例子。頁面載入以後,外部 div 和內部 div 中都會顯示1。當按了遞增按鈕之後,會發現只有內部的1變成了2,繼續按也是一樣,只有內部的數字會遞增。那麼這時候,新手往往就慌了,說好的神奇的雙向繫結呢?

Angular中範圍的坑2

這個時候寶寶就有點小情緒了,stackoverflow走起,官方文檔走起,最後發現確實有解決方案,比如說將 a 寫成一個對象的屬性 data.a

// html<div ng-controller="OuterCtrl">  <span ng-bind="data.a"></span>  <div ng-controller="InnerCtrl">    <span ng-bind="data.a"></span>    <button ng-click="data.a=data.a+1">遞增</button>  </div></div>// javascriptfunction OuterCtrl($scope) {  $scope.data = {    a: 1  };}function InnerCtrl() {}

然後發現,居然可以工作了,兩個數字都跟著遞增了,我是雙向繫結之王……然後就扔一邊也不管具體的原理繼續學習下一部分教程了。這其實就是我當初學習angular的心路曆程,實在慚愧做了應用部署到生產環境之後才想起來去研究研究內部的原理。

坑總是要填的

廢話說了那麼多,坑也去踩了,下面進入填坑階段,也就是這個坑是為什麼會出現為什麼寫成對象的屬性就能解決。其實知道了原理之後,是很容易理解的。angular的內外層範圍之間是基於javascript的原型鏈來實現的繼承,並且只使用了原型鏈繼承方法,有點JavaScript基礎的朋友應該就能瞬間反應過來,子類原型對象中的參考型別值和父類執行個體對象中的參考型別值是引用的同一個,而基本類型值則會覆蓋父類對象中的基本類型值,這其實也是組合繼承存在的原因,因為光用原型鏈繼承會帶來上訴問題,扯得有點遠

總之這裡,我們可以這樣來看待第一個例子:

function OuterCtrl() {  this.a = 1;}function InnerCtrl() {}var outer = new OuterCtrl();InnerCtrl.prototype = outer;var inner = new InnerCtrl();inner.a = inner.a + 1;

這裡,我們將內部的控制器的建構函式的原型對象設定為外部範圍對象,這樣產生的內部範圍對象就繼承了外部對象 outer 中的屬性 a 。這個屬性是個基本類型值,對內部對象的屬性 a 進行訪問的時候,由於內部對象本身不存在這樣的屬性,就會從它的原型對象中尋找,原型對象 outer 中存在這樣的屬性,於是傳回值,沒有問題,但是如果我們對內部範圍對象的 a 屬性賦值的話,問題就出來了。 inner.a = inner.a + 1; 這個語句實際上進行了前面說的尋找 a 屬性值的過程,然後將返回的值賦值給了內部範圍對象的 a 屬性,由於 a 屬性是不存在的,因此建立了一個 a 的基本類型值屬性,屏蔽了外層範圍對象 outer 中的 a 屬性,這個坑就這麼出來了。

因此,如果我們將基本類型值屬性換成參考型別值屬性的話,問題就能夠得到解決,因為他們兩個對象對應的屬性是引用的同一個參考型別值,不管在哪對它進行修改都會反應在所有引用他的對象上。

總結

以上就是關於Angular中範圍需要注意的坑的全部內容,希望本文的內容對大家學習Angular中的範圍能有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.