深入浅析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 相关文章推荐
JavaScript 继承机制的实现(待续)
May 18 Javascript
得到jQuery detach()后节点中的某个值实现代码
Feb 05 Javascript
jQuery中读取json文件示例代码
May 10 Javascript
javascript获取select值的方法分析
Jul 02 Javascript
基于jQuery实现美观且实用的倒计时实例代码
Dec 30 Javascript
利用AngularJs实现京东首页轮播图效果
Sep 08 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
Dec 29 Javascript
微信小程序动态显示项目倒计时效果
Jun 13 Javascript
layui 监听表格复选框选中值的方法
Aug 15 Javascript
vue中tab选项卡的实现思路
Nov 25 Javascript
mpvue 单文件页面配置详解
Dec 02 Javascript
JavaScript静态作用域和动态作用域实例详解
Jun 17 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+jQuery 注册模块的改进(三):更新到Smarty3.1
2014/10/14 PHP
Yii2框架实现数据库常用操作总结
2017/02/08 PHP
php readfile()修改文件上传大小设置
2017/08/11 PHP
PHP Class SoapClient not found解决方法
2018/01/20 PHP
php中加密解密DES类的简单使用方法示例
2020/03/26 PHP
编写自己的jQuery插件简单实现代码
2011/04/19 Javascript
jQuery.query.js 取参数的两点问题分析
2012/08/06 Javascript
jquery ajax同步异步的执行最终解决方案
2013/04/26 Javascript
jQuery判断元素是否存在的可靠方法
2014/05/06 Javascript
js操作css属性实现div层展开关闭效果的方法
2015/05/11 Javascript
详解javascript事件绑定使用方法
2016/10/20 Javascript
手机移动端实现 jquery和HTML5 Canvas的幸运大奖盘特效
2016/12/06 Javascript
Nodejs--post的公式详解
2017/04/29 NodeJs
对angularjs框架下controller间的传值方法详解
2018/10/08 Javascript
关于Vue Router中路由守卫的应用及在全局导航守卫中检查元字段的方法
2018/12/09 Javascript
简单实现vue中的依赖收集与响应的方法
2019/02/18 Javascript
Angular CLI 使用教程指南参考小结
2019/04/10 Javascript
JavaScript中的ES6 Proxy的具体使用
2019/06/16 Javascript
微信小程序监听用户登录事件的实现方法
2019/11/11 Javascript
js实现select下拉框选择
2020/01/11 Javascript
微信小程序scroll-view的滚动条设置实现
2020/03/02 Javascript
[01:14:30]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第二场 8.20.mp4
2019/08/22 DOTA
Python爬虫包 BeautifulSoup  递归抓取实例详解
2017/01/28 Python
python excel转换csv代码实例
2019/08/26 Python
Python简单实现区域生长方式
2020/01/16 Python
python使用for...else跳出双层嵌套循环的方法实例
2020/05/17 Python
在keras中实现查看其训练loss值
2020/06/16 Python
css3实现书本翻页效果的示例代码
2021/03/08 HTML / CSS
recorder.js 基于Html5录音功能的实现
2020/05/26 HTML / CSS
致标枪运动员广播稿
2014/02/06 职场文书
办公室文员岗位职责范本
2014/06/12 职场文书
超市店庆活动方案
2014/08/31 职场文书
“向国旗敬礼”活动策划方案(4篇)
2014/09/27 职场文书
党支部班子“四风”问题自我剖析材料
2014/09/28 职场文书
解除租房协议书
2014/12/03 职场文书
C3 线性化算法与 MRO之Python中的多继承
2021/10/05 Python