深入浅析knockout源码分析之订阅


Posted in Javascript onJuly 12, 2016

Knockout.js是什么?

Knockout是一款很优秀的JavaScript库,它可以帮助你仅使用一个清晰整洁的底层数据模型(data model)即可创建一个富文本且具有良好的显示和编辑功能的用户界面。任何时候你的局部UI内容需要自动更新(比如:依赖于用户行为的改变或者外部的数据源发生变化),KO都可以很简单的帮你实现,并且非常易于维护。

一、主类关系图

深入浅析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相关订阅(还没完全理解作用)。

以上所述是小编给大家介绍的深入浅析knockout源码分析之订阅,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery实现用户注册的表单验证示例
Aug 28 Javascript
如何获取网站icon有哪些可行的方法
Jun 05 Javascript
jQuery截取指定长度字符串代码
Aug 21 Javascript
详解AngularJS中的表格使用
Jun 16 Javascript
JavaScript包装对象使用详解
Jul 09 Javascript
基于javascript实现最简单的选项卡切换效果
May 16 Javascript
Angular 4.x中表单Reactive Forms详解
Apr 25 Javascript
妙用Angularjs实现表格按指定列排序
Jun 23 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
Sep 12 Javascript
vue单页缓存存在的问题及解决方案(小结)
Sep 25 Javascript
原生js实现移动端Touch轮播图的方法步骤
Jan 03 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
May 27 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐二)
Jul 12 #Javascript
JavaScript导航脚本判断当前导航
Jul 12 #Javascript
jQuery bt气泡实现悬停显示及移开隐藏功能的方法
Jul 12 #Javascript
Extjs 点击复选框在表格中增加相关信息行
Jul 12 #Javascript
jQuery插件学习教程之SlidesJs轮播+Validation验证
Jul 12 #Javascript
JavaScript中的事件委托及好处
Jul 12 #Javascript
原生js实现class的添加和删除简单代码
Jul 12 #Javascript
You might like
点评山进PR-D3L三波段收音机
2021/03/02 无线电
PHP可逆加密/解密函数分享
2012/09/25 PHP
php启动时候提示PHP startup的解决方法
2013/05/07 PHP
php基于双向循环队列实现历史记录的前进后退等功能
2015/08/08 PHP
详解PHP中array_rand函数的使用方法
2016/09/11 PHP
php实现购物车功能(以大苹果购物网为例)
2017/03/09 PHP
微信推送功能实现方式图文详解
2019/07/12 PHP
Jquery Ajax学习实例5 向WebService发出请求,返回泛型集合数据的异步调用
2010/03/17 Javascript
javascript获取url上某个参数的方法
2013/11/08 Javascript
浅谈javascript中字符串String与数组Array
2014/12/31 Javascript
jquery插件corner实现圆角边框的方法
2015/03/09 Javascript
jQuery+CSS实现简单切换菜单示例
2016/07/27 Javascript
通过BootStrap实现轮播图的实际应用
2016/09/26 Javascript
Angular ng-repeat指令实例以及扩展部分
2016/12/26 Javascript
vue将后台数据时间戳转换成日期格式
2019/07/31 Javascript
Javascript Web Worker使用过程解析
2020/03/16 Javascript
用十张图详解TensorFlow数据读取机制(附代码)
2018/02/06 Python
浅谈Tensorflow模型的保存与恢复加载
2018/04/26 Python
Python requests库用法实例详解
2018/08/14 Python
Python3+Pycharm+PyQt5环境搭建步骤图文详解
2019/05/29 Python
Python-while 计算100以内奇数和的方法
2019/06/11 Python
python画图——实现在图上标注上具体数值的方法
2019/07/08 Python
python日志模块logbook使用方法
2019/09/19 Python
python烟花效果的代码实例
2020/02/25 Python
python3中布局背景颜色代码分析
2020/12/01 Python
python 解决函数返回return的问题
2020/12/05 Python
HTML5 canvas基本绘图之文字渲染
2016/06/27 HTML / CSS
htnl5利用svg页面高斯模糊的方法
2018/07/20 HTML / CSS
Stefania Mode英国:奢华设计师和时尚服装
2017/10/23 全球购物
工作中的自我评价如何写好
2013/10/28 职场文书
医大实习自我鉴定
2013/12/07 职场文书
一年级数学教学反思
2014/02/01 职场文书
上班迟到检讨书300字
2014/10/18 职场文书
2015年终个人政治思想工作总结
2015/11/24 职场文书
python 如何将两个实数矩阵合并为一个复数矩阵
2021/05/19 Python
MYSQL常用函数介绍
2022/05/05 MySQL