深入浅析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 返回布尔值Is()条件判断方法代码
May 14 Javascript
jquery实现多级下拉菜单的实例代码
Oct 02 Javascript
Enter回车切换输入焦点实现思路与代码兼容各大浏览器
Sep 01 Javascript
jquery中页面Ajax方法$.load的功能使用介绍
Oct 20 Javascript
jquery自定义插件开发之window的实现过程
May 06 Javascript
javascript 实现动态侧边栏实例详解
Nov 11 Javascript
jQuery验证表单格式的使用方法
Jan 10 Javascript
Bootstrap组件之下拉菜单,多级菜单及按钮布局方法实例
May 25 Javascript
浅谈Node模块系统及其模式
Nov 17 Javascript
js实现控制文件拖拽并获取拖拽内容功能
Feb 17 Javascript
vue 优化CDN加速的方法示例
Sep 19 Javascript
Vue通过懒加载提升页面响应速度
May 10 Vue.js
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实用函数分享之去除多余的0
2015/02/06 PHP
thinkPHP实现的省市区三级联动功能示例
2017/05/05 PHP
PHP基于session.upload_progress 实现文件上传进度显示功能详解
2019/08/09 PHP
onpropertypchange
2006/07/01 Javascript
jQuery学习笔记之DOM对象和jQuery对象
2010/12/22 Javascript
jQuery实现长文字部分显示代码
2013/05/13 Javascript
js函数排序的实例代码
2013/07/01 Javascript
js中typeof的用法汇总
2013/12/12 Javascript
javascript 自定义回调函数示例代码
2014/09/26 Javascript
使用JavaScript和C#中获得referer
2014/11/14 Javascript
Atitit.js的键盘按键事件捆绑and事件调度
2016/04/01 Javascript
微信小程序 蓝牙的实现实例代码
2017/06/27 Javascript
AngularJS 将再发布一个重要版本 然后进入长期支持阶段
2018/01/31 Javascript
vue移动端html5页面根据屏幕适配的四种解决方法
2018/10/19 Javascript
js实现搜索栏效果
2018/11/16 Javascript
微信小程序使用canvas自适应屏幕画海报并保存图片功能
2019/07/25 Javascript
vue使用微信扫一扫功能的实现代码
2020/04/11 Javascript
JS hasOwnProperty()方法检测一个属性是否是对象的自有属性的方法
2021/01/29 Javascript
[40:06]DOTA2亚洲邀请赛 4.3 突围赛 Liquid vs VGJ.T 第一场
2018/04/04 DOTA
通过数据库向Django模型添加字段的示例
2015/07/21 Python
python中安装模块包版本冲突问题的解决
2017/05/02 Python
python抖音表白程序源代码
2019/04/07 Python
java中的控制结构(if,循环)详解
2019/06/26 Python
tensorflow2.0的函数签名与图结构(推荐)
2020/04/28 Python
opencv 实现特定颜色线条提取与定位操作
2020/06/02 Python
css3实现冲击波效果的示例代码
2018/01/11 HTML / CSS
分享全球十款超强HTML5开发工具
2014/05/14 HTML / CSS
SQL中where和having的区别
2012/06/17 面试题
大学生全国两会报告感想
2014/03/17 职场文书
教育实践活动对照检查材料
2014/09/23 职场文书
教师年度个人总结
2015/02/11 职场文书
学年个人总结范文
2015/03/05 职场文书
2015年组织委员工作总结
2015/04/23 职场文书
决心书格式范文
2015/09/23 职场文书
2019年教师节:送给所有老师的祝福语
2019/09/05 职场文书
python实现MD5进行文件去重的示例代码
2021/07/09 Python