深入浅析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使用eval或者new Function进行语法检查
Oct 16 Javascript
Jquery ajaxStart()与ajaxStop()方法(实例讲解)
Dec 18 Javascript
jquery制作属于自己的select自定义样式
Nov 23 Javascript
基于AngularJS实现iOS8自带的计算器
Sep 12 Javascript
详解Node.js中的事件机制
Sep 22 Javascript
基于jQuery制作小图标上下滑动特效
Jan 18 Javascript
ztree实现左边动态生成树右边为内容详情功能
Nov 03 Javascript
基于vue实现分页效果
Nov 06 Javascript
JS使用Dijkstra算法求解最短路径
Jan 17 Javascript
Vue父组件如何获取子组件中的变量
Jul 24 Javascript
VUE项目初建和常见问题总结
Sep 12 Javascript
微信小程序实现录音功能
Nov 22 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中对数据库操作的封装
2006/10/09 PHP
解析PHP中$_FILES的使用以及注意事项
2013/07/05 PHP
destoon官方标签大全
2014/06/20 PHP
php实现两表合并成新表并且有序排列的方法
2014/12/05 PHP
PHP数组和explode函数示例总结
2015/05/08 PHP
PHP多进程编程总结(推荐)
2016/07/18 PHP
PHP 实现 WebSocket 协议原理与应用详解
2020/04/22 PHP
Javascript 二维数组
2009/11/26 Javascript
JQuery autocomplete 使用手册
2010/04/01 Javascript
jquery得到font-size属性值实现代码
2013/09/30 Javascript
Js冒泡事件详解及阻止示例
2014/03/21 Javascript
jQuery控制cookie过期时间的方法
2015/04/07 Javascript
JQ实现新浪游戏首页幻灯片
2015/07/29 Javascript
jQuery实现类似标签风格的导航菜单效果代码
2015/08/25 Javascript
JavaScript仿淘宝页面图片滚动加载及刷新回顶部的方法解析
2016/05/24 Javascript
浅谈JS中的!=、== 、!==、===的用法和区别
2016/09/24 Javascript
Angular 2应用的8个主要构造块有哪些
2016/10/17 Javascript
jQuery自定义插件详解及实例代码
2016/12/29 Javascript
简单实现js选项卡切换效果
2017/02/09 Javascript
Bootstrap栅格系统使用方法及页面调整变形的解决方法
2017/03/10 Javascript
Vue实现点击时间获取时间段查询功能
2020/08/21 Javascript
微信小程序实现天气预报功能
2018/07/18 Javascript
Python图像处理之图像的读取、显示与保存操作【测试可用】
2019/01/04 Python
Python实现将字符串的首字母变为大写,其余都变为小写的方法
2019/06/11 Python
通过Python实现Payload分离免杀过程详解
2020/07/13 Python
css3实现wifi信号逐渐增强效果实例
2017/08/09 HTML / CSS
利用CSS3 动画 绘画 圆形动态时钟
2018/03/20 HTML / CSS
关于webview适配H5上传照片或者视频文件的方法
2020/11/04 HTML / CSS
美国第一大药店连锁机构:Walgreens(沃尔格林)
2019/10/10 全球购物
.NET常见笔试题集
2012/12/01 面试题
幼儿教师工作感言
2014/02/14 职场文书
施工协议书范本
2014/04/22 职场文书
校园学雷锋广播稿
2014/10/08 职场文书
2016年万圣节活动总结
2016/04/05 职场文书
新学期小学班主任工作计划
2019/06/21 职场文书
使用CSS设置滚动条样式
2022/01/18 HTML / CSS