深入浅析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 相关文章推荐
使用prototype.js 的时候应该特别注意的几个问题.
Apr 12 Javascript
JavaScript 全角转半角部分
Oct 28 Javascript
jQuery层次选择器选择元素使用介绍
Apr 18 Javascript
JavaScript数组常用方法
Mar 02 Javascript
JS实现屏蔽shift,Ctrl,alt等功能键的方法
Jun 01 Javascript
AngularJS学习笔记之ng-options指令
Jun 16 Javascript
js判断上传文件后缀名是否合法
Jan 28 Javascript
Angular限制input框输入金额(是小数的话只保留两位小数点)
Jul 13 Javascript
Vue.js表单标签中的单选按钮、复选按钮和下拉列表的取值问题
Nov 22 Javascript
Three.js实现简单3D房间布局
Dec 30 Javascript
利用vue-i18n实现多语言切换效果的方法
Jun 19 Javascript
Vue 自适应高度表格的实现方法
May 13 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
ThinkPHP 表单自动验证运用示例
2014/10/13 PHP
php判断两个日期之间相差多少个月份的方法
2015/06/18 PHP
Avengerls vs KG BO3 第三场2.18
2021/03/10 DOTA
与jquery serializeArray()一起使用的函数,主要来方便提交表单
2011/01/31 Javascript
jquery仿QQ商城带左右按钮控制焦点图片切换滚动效果
2013/06/27 Javascript
一个JavaScript递归实现反转数组字符串的实例
2014/10/14 Javascript
微信小程序之MaterialDesign--input组件详解
2017/02/15 Javascript
js实现显示手机号码效果
2017/03/09 Javascript
详解JS中遍历语法的比较
2017/04/07 Javascript
微信小程序 setData的使用方法详解
2017/04/20 Javascript
AngularJS中控制器函数的定义与使用方法示例
2017/10/10 Javascript
vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单
2018/09/14 Javascript
Vue中控制v-for循环次数的实现方法
2018/09/26 Javascript
angular6开发steps步骤条组件
2019/07/04 Javascript
浅谈对于“不用setInterval,用setTimeout”的理解
2019/08/28 Javascript
vue中watch和computed为什么能监听到数据的改变以及不同之处
2019/12/27 Javascript
[14:50]2018DOTA2亚洲邀请赛开幕式
2018/04/03 DOTA
Python内置函数之filter map reduce介绍
2014/11/30 Python
python学习 流程控制语句详解
2016/06/01 Python
Django 限制用户访问频率的中间件的实现
2018/08/23 Python
便捷提取python导入包的属性方法
2018/10/15 Python
对于Python深浅拷贝的理解
2019/07/29 Python
python爬虫 爬取超清壁纸代码实例
2019/08/16 Python
Python数据分析模块pandas用法详解
2019/09/04 Python
python pycharm最新版本激活码(永久有效)附python安装教程
2020/09/18 Python
QT5 Designer 打不开的问题及解决方法
2020/08/20 Python
Python json解析库jsonpath原理及使用示例
2020/11/25 Python
pycharm配置安装autopep8自动规范代码的实现
2021/03/02 Python
面试后的英文感谢信
2014/02/01 职场文书
文明村创建实施方案
2014/03/27 职场文书
小学生读书活动总结
2014/06/30 职场文书
园林技术专业求职信
2014/07/28 职场文书
教师查摆问题及整改措施
2014/10/11 职场文书
银行党员批评与自我批评
2014/10/15 职场文书
打架赔偿协议书范本
2014/10/26 职场文书
2016中秋晚会开幕词
2016/03/03 职场文书