摘要:對(duì)象其實(shí)就是一個(gè)簡(jiǎn)單的。和和就像一個(gè)硬幣的兩面。他們組合在一起就是臟檢查循環(huán)的核心對(duì)于數(shù)據(jù)變化的響應(yīng)。臟值檢測(cè)目的只有監(jiān)控的值發(fā)生改變的時(shí)候我們才執(zhí)行對(duì)應(yīng)的。思路存儲(chǔ)上一次的值,和這一次值的進(jìn)行比對(duì)。中默認(rèn)的為,對(duì)外暴露可修改。
Scope object
Scope對(duì)象其實(shí)就是一個(gè)簡(jiǎn)單的POJO(plain old JavaScript Object)。我們可以給它任意的添加屬性。
// scope.js export default class Scope { } // test.js const scope = new Scope(); scope.aProperty = 1; expect(scope.aProperty).toBe(1);$watch 和 $digest
$watch和$digest就像一個(gè)硬幣的兩面。他們組合在一起就是臟檢查循環(huán)的核心:對(duì)于數(shù)據(jù)變化的響應(yīng)。
$watch:$watch(watchExpression, listener, [objectEquality]);
watchExpression: 監(jiān)聽的數(shù)據(jù)
listener:數(shù)據(jù)發(fā)生變化的時(shí)候調(diào)用
objectEquality: 后面多帶帶說
angularjs中將所有的 watchExpression 存放到一個(gè)叫作$$watcher的數(shù)組中,因此我們創(chuàng)建一個(gè)數(shù)組:
$$watchers = []; $watch(watchFn, listenerFn) { const watcher = { watchFn, listenerFn }; this.$$watchers.push(watcher); }$digest:
它遍歷scope上的所有watchers,計(jì)算 watchExpression ,并且調(diào)用它對(duì)應(yīng)的 listenerFn。
_.forEach(this.$$watchers, watcher => { watcher.listenerFn(); });臟值檢測(cè)
目的:只有監(jiān)控的值發(fā)生改變的時(shí)候我們才執(zhí)行對(duì)應(yīng)的listener。
思路:存儲(chǔ)上一次的值,和這一次值的進(jìn)行比對(duì)。
$digest() { // 將變量聲明提取到循環(huán)外面 let newValue; let oldValue; _.forEach(this.$$watchers, watcher => { newValue = watcher.watchFn(this); // 第一次獲取last的時(shí)候值為undefined oldValue = watcher.last; // 只有當(dāng)新舊值不相等的時(shí)候才執(zhí)行l(wèi)istener if (newValue !== oldValue) { watcher.last = newValue; watcher.listenerFn(newValue, oldValue, this); } }); }初始化watch的值
angularjs中的初始化值為一個(gè)函數(shù):
function initWatchVal() {}
然后將其賦值給watch的last:
const watcher = { watchFn, listenerFn, last: initWacthVal };持續(xù)監(jiān)測(cè)
添加一個(gè)幫助方法,將所有的watchFn運(yùn)行一次,返回一個(gè)boolean值,表示是否有更新:
$digest() { let newValue; let oldValue; // 標(biāo)記是否為臟 let dirty; // 上來(lái)先執(zhí)行一次看是否所有值發(fā)生變化,如果有變化,則第二次執(zhí)行watch do { // 初次進(jìn)來(lái)設(shè)置為false dirty = false; _.forEach(this.$$watchers, watcher => { newValue = watcher.watchFn(this); // 第一次獲取last的時(shí)候值為undefined oldValue = watcher.last; // 只有當(dāng)新舊值不相等的時(shí)候才執(zhí)行l(wèi)istener if (newValue !== oldValue) { dirty = true; watcher.last = newValue; // watcher.listenerFn(newValue, oldValue, this); const temp = oldValue === initWacthVal ? newValue : oldValue; watcher.listenerFn(newValue, temp, this); } }); } while (dirty); }ttl
如果watch一直為不穩(wěn)定的值,我們需要停止臟檢查。angularjs中默認(rèn)的ttl為10,對(duì)外暴露可修改。
// 如果為臟,并且ttl達(dá)到0的時(shí)候 if (dirty && !(ttl--)) { throw "10 digest iterations reached"; }停止臟檢查
添加lastDirtyWatch去判斷,看源碼。
執(zhí)行$digest的時(shí)候?qū)?lastDirtyWatch = null
當(dāng)前watcer 和 lastDirtyWatch 相同的時(shí)候設(shè)置為 null
watch的listener里面包含有watch的時(shí)候,重置為 null
基于值的臟檢查$watch(watchExpression, listener, [objectEquality]);
判斷是否相等要包含數(shù)組和對(duì)象,angularjs內(nèi)置的方法為:
angular.equals(o1, o2);
然后替換原來(lái)的新舊值的判斷:
// 判斷是否相等 function areEqual(newValue, oldValue, valueEq) { if (valueEq) { return _.isEqual(newValue, oldValue); } else { return newValue === oldValue; } }銷毀監(jiān)聽
angularjs中的銷毀是給$watch的時(shí)候返回一個(gè)方法,當(dāng)你調(diào)用的時(shí)候,直接將它從數(shù)組中移除。
$watch(watchFn, listenerFn, valueEq) { const watcher = { watchFn, listenerFn, valueEq, last: initWacthVal }; this.$$watchers.push(watcher); // 新加入一個(gè)watcher的時(shí)候?qū)astDirtyWatch初始化 this.lastDirtyWatch = null; return () => { const index = _.find(this.$$watchers, watcher); if (index >= 0) { this.$$watchers.splice(index, 1); } }; }
對(duì)內(nèi)簡(jiǎn)單的分享,記錄下來(lái)。參照書名:build your own angularjs
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/97849.html
摘要:在講解之前先回顧一下筆者在項(xiàng)目開發(fā)中的工作流變化時(shí)代此時(shí)工作流大致為結(jié)合插件處理視圖處理樣式等庫(kù)此時(shí)由于依賴少手動(dòng)引入各種標(biāo)簽結(jié)合調(diào)試界面時(shí)代利用指令服務(wù)控制器將邏輯拆分為多個(gè)文件利用編譯會(huì)將分為全局樣式和組件樣式下載各種依賴此時(shí)任需要手動(dòng) 在講解 webpack 之前先回顧一下筆者在項(xiàng)目開發(fā)中的工作流變化. jquery 時(shí)代 此時(shí)工作流大致為 jquery 結(jié)合插件處理視圖 bo...
摘要:前綴表示私有變量上述代碼實(shí)現(xiàn)的并不實(shí)用,因?yàn)閷?shí)際上我們需要的是監(jiān)聽的對(duì)象數(shù)據(jù)發(fā)生改變時(shí)才執(zhí)行相應(yīng)的方法。我們使用來(lái)約束遍歷的最大次數(shù),在中默認(rèn)次數(shù)為。 $watch 和 $digest $watch 和 $digest 是數(shù)據(jù)綁定中的核心概念:我們可以使用 $watch 在 scope 中綁定 watcher 用于監(jiān)聽 scope 中發(fā)生的變化,而 $digest 方法的執(zhí)行即是遍歷 ...
摘要:換言之,的對(duì)應(yīng)的,此外它還有。它們共同構(gòu)成的監(jiān)控系統(tǒng)。和是相輔相成的。兩者一起,構(gòu)成了作用域的核心功能數(shù)據(jù)變化的響應(yīng)。迭代的最大值稱為。框架設(shè)計(jì)第三版,敬請(qǐng)期待 angular的ViewModel有一個(gè)專門的官方術(shù)語(yǔ)叫$scope, 它只是一個(gè)普通構(gòu)造器(Scope)的實(shí)例。換言之,它是一個(gè)普通的JS對(duì)象。為了實(shí)現(xiàn)MVVM框架通常宣傳的那種改變數(shù)據(jù)即改變視圖的魔幻效果,它得裝備上更多更...
摘要:本文針對(duì)的讀者具備性能優(yōu)化的相關(guān)知識(shí)雅虎條性能優(yōu)化原則高性能網(wǎng)站建設(shè)指南等擁有實(shí)戰(zhàn)經(jīng)驗(yàn)。這種機(jī)制能減少瀏覽器次數(shù),從而提高性能。僅會(huì)檢查該和它的子,當(dāng)你確定當(dāng)前操作僅影響它們時(shí),用可以稍微提升性能。 搬運(yùn)自: http://atian25.github.io/2014/05/09/angular-performace/ 不知不覺,在項(xiàng)目中用angular已經(jīng)半年多了,踩了很多坑...
摘要:雖然只有個(gè)問題,但是覆蓋了開發(fā)中的各個(gè)方面,有基本的知識(shí)點(diǎn),也有在開發(fā)過程中遇見的問題,同時(shí)也有較為開放性的問題去辨別面試者的基礎(chǔ)水準(zhǔn)和項(xiàng)目經(jīng)驗(yàn)如果自己一年前面試肯定是喜劇到悲劇的轉(zhuǎn)變。 showImg(https://segmentfault.com/img/bVyzEN); 雖然只有10個(gè)問題,但是覆蓋了angular開發(fā)中的各個(gè)方面,有基本的知識(shí)點(diǎn),也有在開發(fā)過程中遇見的問題,同...
閱讀 3529·2021-11-18 10:02
閱讀 3103·2019-08-29 18:34
閱讀 3389·2019-08-29 17:00
閱讀 420·2019-08-29 12:35
閱讀 748·2019-08-28 18:22
閱讀 1910·2019-08-26 13:58
閱讀 1660·2019-08-26 10:39
閱讀 2668·2019-08-26 10:11