深入浅析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 构建客户/服务分离的链接模型中Table分页代码效率初探
Jan 22 Javascript
jQuery制作的别致导航有阴影背景高亮模式窗口
Apr 15 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
Aug 08 Javascript
JS实现图片垂直居中显示小结
Dec 13 Javascript
javaScript基础详解
Jan 19 Javascript
js仿QQ邮箱收件人选择与搜索功能
Feb 10 Javascript
利用策略模式与装饰模式扩展JavaScript表单验证功能
Feb 14 Javascript
JavaScript定义函数_动力节点Java学院整理
Jun 27 Javascript
收集前端面试题之url、href、src
Mar 22 Javascript
angular4笔记系列之内置指令小结
Nov 09 Javascript
微信小程序之数据绑定原理解析
Aug 14 Javascript
vuecli项目构建SSR服务端渲染的实现
Oct 30 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
DedeCMS 核心类TypeLink.class.php摘要笔记
2010/04/07 PHP
php 魔术方法详解
2014/11/11 PHP
php探针不显示内存解决方法
2019/09/17 PHP
javascript instanceof 与typeof使用说明
2010/01/11 Javascript
鼠标焦点离开文本框时验证的js代码
2013/07/19 Javascript
fckeditor粘贴Word时弹出窗口取消的方法
2014/10/30 Javascript
JavaScript中操作Mysql数据库实例
2015/04/02 Javascript
JavaScript事件详细讲解
2016/06/27 Javascript
bootstrap 弹出框modal添加垂直方向滚轴效果
2018/07/09 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
Node.JS在命令行中检查Chrome浏览器是否安装并打开指定网址
2019/05/21 Javascript
layui使用button按钮 点击出现弹层 弹层中加载表单的实例
2019/09/04 Javascript
JS实现随机抽选获奖者
2019/11/07 Javascript
vue实现扫码功能
2020/01/17 Javascript
ssm+vue前后端分离框架整合实现(附源码)
2020/07/08 Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
2020/07/09 Javascript
python之Socket网络编程详解
2016/09/29 Python
Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法
2017/09/08 Python
Python+matplotlib+numpy绘制精美的条形统计图
2018/01/02 Python
Python操作MySQL模拟银行转账
2018/03/12 Python
使用python对excle和json互相转换的示例
2018/10/23 Python
python脚本后台执行方式
2019/12/21 Python
python动态文本进度条的实例代码
2020/01/22 Python
python numpy生成等差数列、等比数列的实例
2020/02/25 Python
python输出数学符号实例
2020/05/11 Python
Python headers请求头如何实现快速添加
2020/11/03 Python
英国品牌男装折扣网站:Brown Bag
2018/03/08 全球购物
PHP面试题大全
2015/10/16 面试题
Java基础类库面试题
2013/09/04 面试题
Unix如何在一行中运行多个命令
2015/05/29 面试题
电气工程及自动化专业自荐书范文
2013/12/18 职场文书
模范家庭事迹材料
2014/02/10 职场文书
法制宣传日活动总结
2014/04/29 职场文书
警察群众路线整改措施
2014/09/26 职场文书
python某漫画app逆向
2021/03/31 Python
MyBatis在注解上使用动态SQL方式(@select使用if)
2022/07/07 Java/Android