深入浅析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插件之easing 动态菜单
Aug 21 Javascript
JQUBar 基于JQUERY的柱状图插件
Nov 23 Javascript
JS字符串累加Array不一定比字符串累加快(根据电脑配置)
May 14 Javascript
利用jquery包将字符串生成二维码图片
Sep 12 Javascript
javascript事件冒泡详解和捕获、阻止方法
Apr 12 Javascript
JS实现的4种数字千位符格式化方法分享
Mar 02 Javascript
3种不同的ContextMenu右键菜单实现代码
Nov 03 Javascript
深入理解JavaScript继承的多种方式和优缺点
May 12 Javascript
深入理解JavaScript创建对象的多种方式以及优缺点
Jun 01 Javascript
Vue.js弹出模态框组件开发的示例代码
Jul 26 Javascript
vue 使用axios 数据请求第三方插件的使用教程详解
Jul 05 Javascript
JavaScript文档对象模型DOM
Nov 20 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实现数组递归转义的方法
2014/08/28 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
thinkphp5.0自定义验证规则使用方法
2017/11/16 PHP
jQuery之排序组件的深入解析
2013/06/19 Javascript
js 立即调用的函数表达式如何写
2014/01/12 Javascript
Jquery实现仿腾讯微博发表广播
2014/11/17 Javascript
JavaScript父子窗体间的调用方法
2015/03/31 Javascript
JS根据key值获取URL中的参数值及把URL的参数转换成json对象
2015/08/26 Javascript
基于jQuery实现返回顶部实例代码
2016/01/01 Javascript
无需 Flash 使用 jQuery 复制文字到剪贴板
2016/04/26 Javascript
常用Javascript函数与原型功能收藏(必看篇)
2016/10/09 Javascript
前端编码规范(3)JavaScript 开发规范
2017/01/21 Javascript
基于VUE选择上传图片并页面显示(图片可删除)
2017/05/25 Javascript
JavaScript之面向对象_动力节点Java学院整理
2017/06/29 Javascript
Nodejs 复制文件/文件夹的方法
2017/08/24 NodeJs
JavaScript使用FileReader实现图片上传预览效果
2020/03/27 Javascript
JS+WCF实现进度条实时监测数据加载量的方法详解
2017/12/19 Javascript
基于Vue sessionStorage实现保留搜索框搜索内容
2020/06/01 Javascript
Python3.遍历某文件夹提取特定文件名的实例
2018/04/26 Python
Python实现的根据IP地址计算子网掩码位数功能示例
2018/05/23 Python
通过python的matplotlib包将Tensorflow数据进行可视化的方法
2019/01/09 Python
Python多项式回归的实现方法
2019/03/11 Python
pymongo中聚合查询的使用方法
2019/03/22 Python
解决.ui文件生成的.py文件运行不出现界面的方法
2019/06/19 Python
20行Python代码实现视频字符化功能
2020/04/13 Python
DJI大疆无人机官方商城:全球领先的无人飞行器研发和生产商
2016/12/21 全球购物
英国奢华护肤、美容和Spa品牌:Temple Spa
2019/11/02 全球购物
三查三看党性分析材料
2014/02/18 职场文书
关于青春的演讲稿
2014/05/05 职场文书
好书伴我成长演讲稿
2014/05/14 职场文书
党的群众路线教育实践活动个人剖析材料
2014/10/07 职场文书
2016大学生入党积极分子心得体会
2016/01/06 职场文书
go mod 安装依赖 unkown revision问题的解决方案
2021/05/06 Golang
JavaScript继承的三种方法实例
2021/05/12 Javascript
《游戏王:大师决斗》将推出新卡牌包4月4日上线
2022/03/31 其他游戏
详解CSS3浏览器兼容
2022/12/24 HTML / CSS