深入浅析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 相关文章推荐
DHTML Slide Show script图片轮换
Mar 03 Javascript
利用javascript实现全部删或清空所选的操作
May 27 Javascript
javascript中call,apply,bind的用法对比分析
Feb 12 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
Mar 04 Javascript
js实现带缓冲效果的仿QQ面板折叠菜单代码
Sep 06 Javascript
基于原生JS实现图片裁剪
Aug 01 Javascript
基于jQuery实现顶部导航栏功能
Dec 27 Javascript
Bootstrap导航条学习使用(一)
Feb 08 Javascript
详解AngularJS脏检查机制及$timeout的妙用
Jun 19 Javascript
基于angular-utils-ui-breadcrumbs使用心得(分享)
Nov 03 Javascript
在vue+element ui框架里实现lodash的debounce防抖
Nov 13 Javascript
JavaScript内置对象之Array的使用小结
May 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
56.com视频采集接口程序(PHP)
2007/09/22 PHP
php身份证号码检查类实例
2015/06/18 PHP
PHP接收json 并将接收数据插入数据库的实现代码
2015/12/01 PHP
PHP实现验证码校验功能
2017/11/16 PHP
PHP实现创建一个RPC服务操作示例
2020/02/23 PHP
ASP中进行HTML数据及JS数据编码函数
2009/11/11 Javascript
用AJAX返回HTML片段中的JavaScript脚本
2010/01/04 Javascript
jquery插件 cluetip 关键词注释
2010/01/12 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
使用百度地图api实现根据地址查询经纬度
2014/12/11 Javascript
JQuery选择器绑定事件及修改内容的方法
2015/01/23 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
2016/01/27 Javascript
详谈JavaScript的闭包及应用
2017/01/17 Javascript
原生JS实现简单放大镜效果
2017/02/08 Javascript
手把手教你如何使用nodejs编写cli命令行
2018/11/05 NodeJs
在vue项目中使用sass语法问题
2019/07/18 Javascript
在Vue环境下利用worker运行interval计时器的步骤
2019/08/01 Javascript
element-ui 远程搜索组件el-select在项目中组件化的实现代码
2019/12/04 Javascript
JavaScript 判断数据类型的4种方法
2020/09/11 Javascript
一分钟学会JavaScript中的try-catch
2020/12/14 Javascript
python基础教程之序列详解
2014/08/29 Python
Python警察与小偷的实现之一客户端与服务端通信实例
2014/10/09 Python
Python中利用sorted()函数排序的简单教程
2015/04/27 Python
python清除字符串里非数字字符的方法
2015/07/02 Python
关于python的bottle框架跨域请求报错问题的处理方法
2017/03/19 Python
pandas.DataFrame选取/排除特定行的方法
2018/07/03 Python
Python批量删除只保留最近几天table的代码实例
2019/04/01 Python
Django 查询数据库并返回页面的例子
2019/08/12 Python
Python绘图实现显示中文
2019/12/04 Python
美国波西米亚风格服装品牌:Show Me Your Mumu
2018/01/05 全球购物
亚马逊新加坡官方网站:Amazon.sg
2020/03/25 全球购物
办公室保洁员岗位职责
2013/12/02 职场文书
应用艺术毕业生的自我评价
2013/12/04 职场文书
劲霸男装广告词
2014/03/21 职场文书
个人函授自我鉴定
2014/03/25 职场文书
旅游安全责任协议书
2016/03/22 职场文书