99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

源碼講解knockout依賴屬性

發(fā)布時(shí)間:2016-07-28 20:10  回復(fù):0  查看:2567   最后回復(fù):2016-07-28 20:10  

knockout依賴屬性是什么?也許看了教程還是迷迷糊糊,這里就給大家用源碼來一個(gè)knockout學(xué)習(xí)教程吧,希望大家能夠弄懂knockout依賴屬性

 

一、序列圖

源碼講解knockout依賴屬性

一、主要代碼文件

 

1dependentObservable.js:主要包含ko.computed相關(guān)方法的處理
2、dependencyDetection.js:主要包含依賴的監(jiān)控上下文對(duì)象。

三、主要邏輯

 

1、首先為某個(gè)屬性定義 一個(gè)computed對(duì)象,如下源碼:

 

var vModel = function(){

        this.fName = ko.observable('fName'),

        this.lName= ko.observable('lName'),

        this.name= ko.computed(function () { //監(jiān)控依賴對(duì)象

            return this.fName() + '-' + this.lName();

        },this);

    };

 

2、當(dāng)代碼在執(zhí)行ko.computed方法,求值方法被作為參數(shù)傳入,并賦值給optionsread屬性
3、創(chuàng)建一個(gè)state字面量對(duì)象,其中包含read、write屬性,如下代碼:

 

var state = {

        latestValue: undefined,

        isStale: true,

        isBeingEvaluated: false,

        suppressDisposalUntilDisposeWhenReturnsFalse: false,

        isDisposed: false,

        pure: false,

        isSleeping: false,

        readFunction: options["read"],

        evaluatorFunctionTarget: evaluatorFunctionTarget || options["owner"],

        disposeWhenNodeIsRemoved: options["disposeWhenNodeIsRemoved"] || options.disposeWhenNodeIsRemoved || null,

        disposeWhen: options["disposeWhen"] || options.disposeWhen,

        domNodeDisposalCallback: null,

        dependencyTracking: {},

        dependenciesCount: 0,

        evaluationTimeoutInstance: null

    };

4、生成computedObservable對(duì)象(function),然后將state附加到_state屬性上,則擴(kuò)展為發(fā)布/訂閱對(duì)象。
5、擴(kuò)展computedFn所有方法和屬性到computedObservable對(duì)象上

// Inherit from 'subscribable'

    if (!ko.utils.canSetPrototype) {

        // 'subscribable' won't be on the prototype chain unless we put it there directly

        ko.utils.extend(computedObservable, ko.subscribable['fn']);

    }

    ko.subscribable['fn'].init(computedObservable); //執(zhí)行發(fā)布/訂閱對(duì)象的init方法,用于初始化發(fā)布/訂閱對(duì)象。

 

    // Inherit from 'computed'

    ko.utils.setPrototypeOfOrExtend(computedObservable, computedFn);

6、然后執(zhí)行computedObservableevaluateImmediate方法,此方法中最重的三點(diǎn):
   6.1、在evaluateImmediate_CallReadWithDependencyDetection方法中,創(chuàng)建了依賴監(jiān)控對(duì)象,并添加到依賴監(jiān)控上下文中

var isInitial = state.pure ? undefined : !state.dependenciesCount,   // If we're evaluating when there are no previous dependencies, it must be the first time

            dependencyDetectionContext = {

                computedObservable: computedObservable,

                disposalCandidates: state.dependencyTracking,

                disposalCount: state.dependenciesCount

            };

 

        ko.dependencyDetection.begin({

            callbackTarget: dependencyDetectionContext,

            callback: computedBeginDependencyDetectionCallback,

            computed: computedObservable,

            isInitial: isInitial

        });

    6.2、然后調(diào)用evaluateImmediate_CallReadThenEndDependencyDetection方法,參數(shù)傳遞的state(在ko.computed方法中定義的)、dependencyDetectionContext(依賴監(jiān)控對(duì)象)
    6.3、其中用到了try catch finall方式,確保ko.dependencyDetection.end方法的執(zhí)行

try {

            var readFunction = state.readFunction;

            return state.evaluatorFunctionTarget ? readFunction.call(state.evaluatorFunctionTarget) : readFunction();

        } finally {

            ko.dependencyDetection.end();

 

            // For each subscription no longer being used, remove it from the active subscriptions list and dispose it

            if (dependencyDetectionContext.disposalCount && !state.isSleeping) {

                ko.utils.objectForEach(dependencyDetectionContext.disposalCandidates, computedDisposeDependencyCallback);

            }

 

            state.isStale = false;

        }

7、在執(zhí)行ko.computedreadFunction方法時(shí),其中就執(zhí)行了ko.observable方法(執(zhí)行的是read),這時(shí)就會(huì)去調(diào)用ko.dependencyDetection.registerDependency方法(參數(shù)為此函數(shù)對(duì)象)

function observable() {

        if (arguments.length > 0) {

            // Write

 

            // Ignore writes if the value hasn't changed

            if (observable.isDifferent(observable[observableLatestValue], arguments[0])) {

                observable.valueWillMutate();

                observable[observableLatestValue] = arguments[0];

                observable.valueHasMutated();

            }

            return this; // Permits chained assignments        }

        else {

            debugger;

            // Read

            ko.dependencyDetection.registerDependency(observable); //執(zhí)行依賴

            return observable[observableLatestValue];

        }

    }

8、在ko.dependencyDetection中的registerDependency方法內(nèi),首先會(huì)判斷ko.observable是否為訂閱對(duì)象,如果是則執(zhí)行begin加入的callbak函數(shù).

registerDependency: function (subscribable) { //注入到相關(guān)依賴屬性

            if (currentFrame) {

                if (!ko.isSubscribable(subscribable))

                    throw new Error("Only subscribable things can act as dependencies");

                currentFrame.callback.call(currentFrame.callbackTarget, subscribable, subscribable._id || (subscribable._id = getId()));

            }

        }

9、執(zhí)行evaluateImmediate方法后,然后注冊(cè)Dom移除回調(diào)事件。

if (state.disposeWhenNodeIsRemoved && computedObservable.isActive()) {

        ko.utils.domNodeDisposal.addDisposeCallback(state.disposeWhenNodeIsRemoved, state.domNodeDisposalCallback = function () {

            computedObservable.dispose();

        });

    }

10、返回computedObservable對(duì)象

四、補(bǔ)充說明

 

1、ko.dependencyDetection中有ignore方法,他主要實(shí)現(xiàn)的是一個(gè)異步鎖,讓callbcak處于鎖的狀態(tài)執(zhí)行

ignore: function (callback, callbackTarget, callbackArgs) { //按順序s執(zhí)行依賴,但不觸發(fā)訂閱。

            try {

                begin();

                return callback.apply(callbackTarget, callbackArgs || []);

            } finally {

                end();

            }

        }

2、ko.computed 與 ko.dependentObservable是相同的。

 

 

 

 

原文來自:博客園/小龍女先生

您還未登錄,請(qǐng)先登錄

熱門帖子

最新帖子

?