zoukankan      html  css  js  c++  java
  • knockout源码分析之订阅

    一、主类关系图

    二、类职责

    2.1、observable(普通监控对象类)

    observable(他其是一个function)的内部实现:
    1.首先声明一个名为observable的fn(这个可以说是一个类)
    2.增加一个ko惟一的latestValue(最新值)属性来存储形参传入的值
    3.如果支持原生__proto__属性就利用hasOwnProperty来判断属性是否存在的方式来继承,判断__proto__代码(在utils类中)

    var canSetPrototype = ({ __proto__: [] } instanceof Array);

    4.ko.subscribable的fn属性的init方法对observable进行初始化(主要增加订阅、发布相关属性)
    5.observable再继承observabelFn相关属性和方法(observabelFn包含观察、值变化前、值变化后的执行策略)
    // 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方法的实现(如果传入参数就是设置,无参则是获取)
    7、此类还提供了hasPrototype(判断指定实例是否拥有此属性)、isObservable(判断指定实例是否为监控对象)、isWriteableObservable(是否为可写的监控对象)。

    2.2、observableArray(数组监控对象类)

    1.先执行ko.observable方法,让其对象变为一个可监控的类(名为result);
    2.然后扩展ko.observableArray中的fn对象(ko.observabelArray的fn重写了数组相关的操作方法,如remove、push等)
    3.通过extends扩展一个方法(trackArrayChanages,详细介绍见2.5)
    4.返回扩展好的result对象。

    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(订阅对象类)

    1.实现订阅、发布的功能模块,对observable、observableArray来说是必不可少的基类
    2.这里有一个subscrible方法,用于对监控对象变化的订阅接口,开发则可以用此继切入点

    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方法加入的扩展类(如observableArray.changeTracking扩展类)
    4.extend扩展的方法,会在监控对象注册后立即执行,传入参数为target(当前对象)、options(extend调用时传入的参数)
    5.extend就是安装扩展的方法,他会立即执行扩展中的代码。

    2.4、extends(扩展监控对象类)

    1.ko默认的扩展集合
    2.提供一个applyExtenders方法来安装扩展

    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(扩展监控对象的一个具体实现)

    1.此扩展主要实现对数组变化的监控,然后计算数组的差异,以及触发相关的订阅事件
    2.cacheDiffForKnownOperation:缓存对数组的操作,以备差异比较
    3.beforeSubscriptionAdd、afterSubscriptionRemove相关订阅(还没完全理解作用)。

  • 相关阅读:
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Linux下的iwpriv(iwlist、iwconfig)的简单应用
    OCX控件的注册卸载,以及判断是否注册
    .OCX、.dll文件注册命令Regsvr32的使用
  • 原文地址:https://www.cnblogs.com/cqhaibin/p/5658873.html
Copyright © 2011-2022 走看看