學習Angular中作用域需要注意的坑

2022-10-06 19:24:10 字數 2213 閱讀 3533

angular作用域

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

angular作用域的坑

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

angular中作用域的坑1

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

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

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

// html

"a">

// j**ascript

function outerctrl($scope)

function innerctrl() {}

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

angular中作用域的坑2

這個時候寶寶就有點小情緒了,stackoverflow走起,官方文件走起,最後發現確實有解決方法,比如說將 a 寫成乙個物件的屬性data.a:

// html

// j**ascript

function outerctrl($scope) ;

}function innerctrl() {}

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

坑總是要填的

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

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

function outerctrl()

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 作用域與事件

從作用域往上傳送事件,使用scope.emit scope.emit someevent 從作用域往下傳送事件,使用scope.broadcast scope.broadcast someevent 這兩個方法的第二個引數是要隨事件帶出的資料。注意,這兩種方式傳播事件,事件的傳送方自己也會收到乙份。...

angular中作用域的生命週期

先扯淡是慣例 生命對於人而言是再重要不過的東西了,但你不太可能每天去考慮自己離生命結束還有多久,生命週期就更談不上了,人的生命一旦結束就不會再次開始,如果你堅持認為生命有輪迴,好吧,咱倆的淡扯不到一塊去。但對於angular的作用域來講,它確實是有生命週期的,也就是說它可以死而復生,而且一定是在你需...

js中的作用域和作用域

作用域是在執行時 中的某些特定部分中變數,函式和物件的可訪問性 簡單的說就好似變數能起到作用的範圍 區域性作用域 也可以叫做函式作用域 一般只在固定的 片段內可訪問到,最常見的例如函式內部 如下 在我們在函式中用var關鍵字宣告乙個 變數 a 在函式外輸出a的值 function scope con...