深入浅析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 相关文章推荐
JSON.stringify转换JSON时日期时间不准确的解决方法
Aug 08 Javascript
jQuery 实现侧边浮动导航菜单效果
Dec 26 Javascript
jquery实现鼠标滑过小图时显示大图的方法
Jan 14 Javascript
jQuery()方法的第二个参数详解
Apr 29 Javascript
JS+CSS实现仿雅虎另类滑动门切换效果
Oct 13 Javascript
JavaScript优化专题之Loading and Execution加载和运行
Jan 20 Javascript
js实现购物车功能
Jun 12 Javascript
学习node.js 断言的使用详解
Mar 18 Javascript
浅谈目前可以使用ES10的5个新特性
Jun 25 Javascript
vuex 动态注册方法 registerModule的实现
Jul 03 Javascript
p5.js绘制创意自画像
Nov 04 Javascript
Vue页面切换和a链接的本质区别详解
Nov 12 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
使用phpQuery采集网页的方法
2013/11/13 PHP
php生成短网址/短链接原理和用法实例分析
2020/05/29 PHP
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
一个简单的js渐显(fadeIn)渐隐(fadeOut)类
2010/06/19 Javascript
用Jquery实现多级下拉框无刷新的联动
2010/12/22 Javascript
详细解读AngularJS中的表单验证编程
2015/06/19 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
2015/11/30 Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
2016/05/21 Javascript
JS获取一个未知DIV高度的方法
2016/08/09 Javascript
js中json处理总结之JSON.parse
2016/10/14 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
2017/02/21 Javascript
vue2.0的contextmenu右键弹出菜单的实例代码
2017/07/24 Javascript
js学习总结之DOM2兼容处理重复问题的解决方法
2017/07/27 Javascript
jQuery实现IE输入框完成placeholder标签功能的方法
2017/09/20 jQuery
JS面向对象的程序设计相关知识小结
2018/05/26 Javascript
基于node.js实现爬虫的讲解
2019/02/18 Javascript
vue 路由守卫(导航守卫)及其具体使用
2020/02/25 Javascript
Python比较两个图片相似度的方法
2015/03/13 Python
详解如何利用Cython为Python代码加速
2018/01/27 Python
python 删除指定时间间隔之前的文件实例
2018/04/24 Python
详解Python3.6安装psutil模块和功能简介
2018/05/30 Python
详解重置Django migration的常见方式
2019/02/15 Python
Python绘制全球疫情变化地图的实例代码
2020/04/20 Python
使用CSS3制作倾斜导航条和毛玻璃效果
2017/09/12 HTML / CSS
NBA欧洲商店(法国):NBA Europe Store FR
2016/10/19 全球购物
英国婴儿产品专家:Samuel Johnston
2020/04/20 全球购物
写好自荐信要注意的问题
2013/11/10 职场文书
2014年学习雷锋活动总结
2014/03/01 职场文书
党员教师工作决心书
2014/03/13 职场文书
节约用水的口号
2014/06/20 职场文书
节水倡议书
2015/01/19 职场文书
有关朝花夕拾的读书笔记
2015/06/29 职场文书
实习员工转正的评语汇总,以备不时之需
2019/12/17 职场文书
用PYTHON去计算88键钢琴的琴键频率和音高
2022/04/10 Python
MySQL控制流函数(-if ,elseif,else,case...when)
2022/07/07 MySQL
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript