深入浅析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 相关文章推荐
Firebug 字幕文件JSON地址获取代码
Oct 28 Javascript
JavaScript模板入门介绍
Sep 26 Javascript
JS 去除Array中的null值示例代码
Nov 20 Javascript
iframe的onreadystatechange事件在firefox下的使用
Apr 16 Javascript
jQuery实现可用于博客的动态滑动菜单
Mar 09 Javascript
纯js代码实现简单计算器
Dec 02 Javascript
理解javascript中的严格模式
Feb 01 Javascript
Jquery实现上下移动和排序代码
Oct 17 Javascript
jquery插件canvaspercent.js实现百分比圆饼效果
Jul 18 jQuery
浅谈node模块与npm包管理工具
Jan 03 Javascript
vue-resourc发起异步请求的方法
Feb 11 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
Jan 07 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
PHP 创建文件(文件夹)以及目录操作代码
2010/03/04 PHP
PHP 简易输出CSV表格文件的方法详解
2013/06/20 PHP
为你总结一些php系统类函数
2015/10/21 PHP
Yii数据模型中rules类验证器用法分析
2016/07/15 PHP
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
非常好用的JsonToString 方法 简单实例
2013/07/18 Javascript
jquery 判断滚动条到达了底部和顶端的方法
2014/04/02 Javascript
js实现简单的购物车有图有代码
2014/05/26 Javascript
bootstrap table 服务器端分页例子分享
2015/02/10 Javascript
javascript实现捕捉键盘上按下的键
2015/05/05 Javascript
JavaScript的代码编写格式规范指南
2015/12/07 Javascript
jQuery使用模式窗口实现在主页面和子页面中互相传值的方法
2016/03/01 Javascript
nodeJS删除文件方法示例
2016/12/25 NodeJs
JS轮播图中缓动函数的封装
2020/11/25 Javascript
Vue.js学习之计算属性
2017/01/22 Javascript
jQuery操作css样式
2017/05/15 jQuery
微信小程序实现美团菜单
2018/06/06 Javascript
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
2018/09/25 Javascript
微信小程序request请求封装,验签代码实例
2019/12/04 Javascript
three.js着色器材质的内置变量示例详解
2020/08/16 Javascript
Vue实现简单购物车功能
2020/12/13 Vue.js
[02:29]完美世界高校联赛上海赛区回顾
2015/12/15 DOTA
关于python的list相关知识(推荐)
2017/08/30 Python
Python搜索引擎实现原理和方法
2017/11/27 Python
python文件操作之批量修改文件后缀名的方法
2018/08/10 Python
详细介绍pandas的DataFrame的append方法使用
2019/07/31 Python
解决paramiko执行命令超时的问题
2020/04/16 Python
如何在VSCode下使用Jupyter的教程详解
2020/07/13 Python
使用HTML5做个画图板的方法介绍
2013/05/03 HTML / CSS
Banana Republic欧盟:美国都市简约风格的代表品牌
2018/05/09 全球购物
德国婴儿服装和婴儿用品购买网站:Baby Sweets
2019/12/08 全球购物
自荐信写法介绍
2014/01/25 职场文书
党员自我剖析材料
2014/08/31 职场文书
水利局群众路线专题民主生活会发言材料
2014/09/21 职场文书
教师自查自纠工作情况报告
2014/10/29 职场文书
党支部培养考察意见
2015/06/02 职场文书