深入浅析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 相关文章推荐
ajax请求get与post的区别总结
Nov 04 Javascript
js实现倒计时时钟的示例代码
Dec 17 Javascript
javascript表单验证使用示例(javascript验证邮箱)
Jan 07 Javascript
基于jQuery实现自动轮播旋转木马特效
Nov 02 Javascript
快速解决jquery.touchSwipe左右滑动和垂直滚动条冲突
Apr 15 Javascript
bootstrapfileinput实现文件自动上传
Nov 08 Javascript
VueJS如何引入css或者less文件的一些坑
Apr 25 Javascript
自定义vue全局组件use使用、vuex的使用详解
Jun 14 Javascript
js+html5实现页面可刷新的倒计时效果
Jul 15 Javascript
vue 刷新之后 嵌套路由不变 重新渲染页面的方法
Sep 13 Javascript
layui使用数据表格实现购物车功能
Jul 26 Javascript
Vuex 模块化使用详解
Jul 31 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在线代理转向代码
2012/05/05 PHP
ThinkPHP项目分组配置方法分析
2016/03/23 PHP
PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)
2016/11/15 PHP
php编程实现简单的网页版计算器功能示例
2017/04/26 PHP
PHP实现关键字搜索后描红功能示例
2019/07/03 PHP
jQuery弹出层始终垂直居中相对于屏幕或当前窗口
2013/04/01 Javascript
使用GruntJS构建Web程序之Tasks(任务)篇
2014/06/06 Javascript
JavaScript返回0-1之间随机数的方法
2015/04/06 Javascript
jQuery中animate动画第二次点击事件没反应
2015/05/07 Javascript
一些实用性较高的js方法
2016/04/19 Javascript
浅谈js多维数组和hash数组定义和使用
2016/07/27 Javascript
解决vue 绑定对象内点击事件失效问题
2018/09/05 Javascript
深入了解query和params的使用区别
2019/06/24 Javascript
解决vue自定义全局消息框组件问题
2019/11/22 Javascript
js实现简单的日历显示效果函数示例
2019/11/25 Javascript
vue路由传参的基本实现方式小结【三种方式】
2020/02/05 Javascript
浅谈vue 组件中的setInterval方法和window的不同
2020/07/30 Javascript
vue界面发送表情的实现代码
2020/09/11 Javascript
Python 装饰器深入理解
2017/03/16 Python
使用pandas把某一列的字符值转换为数字的实例
2019/01/29 Python
利用python在excel里面直接使用sql函数的方法
2019/02/08 Python
Python简易版图书管理系统
2019/08/12 Python
解决安装新版PyQt5、PyQT5-tool后打不开并Designer.exe提示no Qt platform plugin的问题
2020/04/24 Python
使用gunicorn部署django项目的问题
2020/12/30 Python
次世代生活态度:Hypebeast
2018/07/05 全球购物
为什么Runtime.exec(“ls”)没有任何输出?
2014/10/03 面试题
采购部主管岗位职责
2014/01/01 职场文书
房屋买卖委托书格式范本格式
2014/10/13 职场文书
2015新年寄语(一句话)
2014/12/08 职场文书
2014年党小组工作总结
2014/12/20 职场文书
长城的导游词
2015/01/30 职场文书
杜甫草堂导游词
2015/02/03 职场文书
有关三国演义的读书笔记
2015/06/25 职场文书
青年联谊会致辞
2015/07/31 职场文书
《秋天的怀念》教学反思
2016/02/17 职场文书
Python中OpenCV实现简单车牌字符切割
2021/06/11 Python