深入淺析knockout源碼分析之訂閱
Knockout.js是什么?
Knockout是一款很優(yōu)秀的JavaScript庫,它可以幫助你僅使用一個(gè)清晰整潔的底層數(shù)據(jù)模型(data model)即可創(chuàng)建一個(gè)富文本且具有良好的顯示和編輯功能的用戶界面。任何時(shí)候你的局部UI內(nèi)容需要自動(dòng)更新(比如:依賴于用戶行為的改變或者外部的數(shù)據(jù)源發(fā)生變化),KO都可以很簡單的幫你實(shí)現(xiàn),并且非常易于維護(hù)。
一、主類關(guān)系圖
二、類職責(zé)
2.1、observable(普通監(jiān)控對(duì)象類)
observable(他其是一個(gè)function)的內(nèi)部實(shí)現(xiàn):
1.首先聲明一個(gè)名為observable的fn(這個(gè)可以說是一個(gè)類)
2.增加一個(gè)ko惟一的latestValue(最新值)屬性來存儲(chǔ)形參傳入的值
3.如果支持原生__proto__屬性就利用hasOwnProperty來判斷屬性是否存在的方式來繼承,判斷__proto__代碼(在utils類中)
var canSetPrototype = ({ __proto__: [] } instanceof Array);
4.ko.subscribable的fn屬性的init方法對(duì)observable進(jìn)行初始化(主要增加訂閱、發(fā)布相關(guān)屬性)
5.observable再繼承observabelFn相關(guān)屬性和方法(observabelFn包含觀察、值變化前、值變化后的執(zhí)行策略)
// Define prototype for observables var observableFn = { 'equalityComparer': valuesArePrimitiveAndEqual, peek: function() { return this[observableLatestValue]; }, valueHasMutated: function () { this['notifySubscribers'](this[observableLatestValue]); }, valueWillMutate: function () { this['notifySubscribers'](this[observableLatestValue], 'beforeChange'); } };
6.返回observable方法的實(shí)現(xiàn)(如果傳入?yún)?shù)就是設(shè)置,無參則是獲?。?/p>
7、此類還提供了hasPrototype(判斷指定實(shí)例是否擁有此屬性)、isObservable(判斷指定實(shí)例是否為監(jiān)控對(duì)象)、isWriteableObservable(是否為可寫的監(jiān)控對(duì)象)。
2.2、observableArray(數(shù)組監(jiān)控對(duì)象類)
1.先執(zhí)行ko.observable方法,讓其對(duì)象變?yōu)橐粋€(gè)可監(jiān)控的類(名為result);
2.然后擴(kuò)展ko.observableArray中的fn對(duì)象(ko.observabelArray的fn重寫了數(shù)組相關(guān)的操作方法,如remove、push等)
3.通過extends擴(kuò)展一個(gè)方法(trackArrayChanages,詳細(xì)介紹見2.5)
4.返回?cái)U(kuò)展好的result對(duì)象。
ko.observableArray = function (initialValues) { initialValues = initialValues || []; if (typeof initialValues != 'object' || !('length' in initialValues)) throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined."); var result = ko.observable(initialValues); ko.utils.setPrototypeOfOrExtend(result, ko.observableArray['fn']); return result.extend({'trackArrayChanges':true}); };
2.3、subscribable(訂閱對(duì)象類)
1.實(shí)現(xiàn)訂閱、發(fā)布的功能模塊,對(duì)observable、observableArray來說是必不可少的基類
2.這里有一個(gè)subscrible方法,用于對(duì)監(jiān)控對(duì)象變化的訂閱接口,開發(fā)則可以用此繼切入點(diǎn)
subscribe: function (callback, callbackTarget, event) { var self = this; event = event || defaultEvent; var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback; var subscription = new ko.subscription(self, boundCallback, function () { ko.utils.arrayRemoveItem(self._subscriptions[event], subscription); if (self.afterSubscriptionRemove) self.afterSubscriptionRemove(event); }); if (self.beforeSubscriptionAdd) self.beforeSubscriptionAdd(event); if (!self._subscriptions[event]) self._subscriptions[event] = []; self._subscriptions[event].push(subscription); return subscription; }
3.extend:此方法用于添加extends方法加入的擴(kuò)展類(如observableArray.changeTracking擴(kuò)展類)
4.extend擴(kuò)展的方法,會(huì)在監(jiān)控對(duì)象注冊后立即執(zhí)行,傳入?yún)?shù)為target(當(dāng)前對(duì)象)、options(extend調(diào)用時(shí)傳入的參數(shù))
5.extend就是安裝擴(kuò)展的方法,他會(huì)立即執(zhí)行擴(kuò)展中的代碼。
2.4、extends(擴(kuò)展監(jiān)控對(duì)象類)
1.ko默認(rèn)的擴(kuò)展集合
2.提供一個(gè)applyExtenders方法來安裝擴(kuò)展
function applyExtenders(requestedExtenders) { var target = this; if (requestedExtenders) { ko.utils.objectForEach(requestedExtenders, function(key, value) { var extenderHandler = ko.extenders[key]; if (typeof extenderHandler == 'function') { target = extenderHandler(target, value) || target; } }); } return target; }
2.5、observableArray.changeTracking(擴(kuò)展監(jiān)控對(duì)象的一個(gè)具體實(shí)現(xiàn))
1.此擴(kuò)展主要實(shí)現(xiàn)對(duì)數(shù)組變化的監(jiān)控,然后計(jì)算數(shù)組的差異,以及觸發(fā)相關(guān)的訂閱事件
2.cacheDiffForKnownOperation:緩存對(duì)數(shù)組的操作,以備差異比較
3.beforeSubscriptionAdd、afterSubscriptionRemove相關(guān)訂閱(還沒完全理解作用)。
以上所述是小編給大家介紹的深入淺析knockout源碼分析之訂閱,希望對(duì)大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Knockoutjs 學(xué)習(xí)系列(二)花式捆綁
- Knockoutjs 學(xué)習(xí)系列(一)ko初體驗(yàn)
- BootstrapTable與KnockoutJS相結(jié)合實(shí)現(xiàn)增刪改查功能【二】
- BootstrapTable與KnockoutJS相結(jié)合實(shí)現(xiàn)增刪改查功能【一】
- Knockout text綁定DOM的使用方法
- Knockout visible綁定使用方法
- Knockout數(shù)組(observable)使用詳解示例
- Knockoutjs快速入門(經(jīng)典)
- Knockoutjs的環(huán)境搭建教程
- ko knockoutjs動(dòng)態(tài)屬性綁定技巧應(yīng)用
- 用Javascript評(píng)估用戶輸入密碼的強(qiáng)度(Knockout版)
相關(guān)文章
實(shí)現(xiàn)div可編輯的常見方法總結(jié)
實(shí)現(xiàn)div可編輯的常見方法總結(jié)...2007-04-04js+flash實(shí)現(xiàn)的5圖變換效果廣告代碼(附演示與demo源碼下載)
這篇文章主要介紹了js+flash實(shí)現(xiàn)的5圖變換效果廣告代碼,涉及JavaScript結(jié)合flash調(diào)用圖片實(shí)現(xiàn)幻燈廣告效果,并附帶演示與demo源碼供讀者下載參考,需要的朋友可以參考下2016-04-04在LayUI圖片上傳中,解決由跨域問題引起的請求接口錯(cuò)誤的方法
今天小編就為大家分享一篇在LayUI圖片上傳中,解決由跨域問題引起的請求接口錯(cuò)誤的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09JS+CSS實(shí)現(xiàn)滾動(dòng)數(shù)字時(shí)鐘效果
本篇文章教給大家用JS代碼配合CSS樣式來實(shí)現(xiàn)滾動(dòng)時(shí)鐘的動(dòng)畫效果,一起來學(xué)習(xí)下。2017-12-12