深入浅析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 相关文章推荐
滚动条变色 隐藏滚动条与双击网页自动滚屏显示代码
Dec 28 Javascript
体验js中splice()的强大(插入、删除或替换数组的元素)
Jan 16 Javascript
js获得页面的高度和宽度的方法
Feb 23 Javascript
浅析js预加载/延迟加载
Sep 25 Javascript
Javascript变量的作用域和作用域链详解
Apr 02 Javascript
基于jQuery插件实现环形图标菜单旋转切换特效
May 15 Javascript
javascript编程异常处理实例小结
Nov 30 Javascript
实例详解jQuery Mockjax 插件模拟 Ajax 请求
Jan 12 Javascript
jQuery使用Layer弹出层插件闪退问题
Dec 22 Javascript
JavaScript常见事件对象与操作实例总结
Jan 05 Javascript
在vue中利用全局路由钩子给url统一添加公共参数的例子
Nov 01 Javascript
vue穿梭框实现上下移动
Jan 29 Vue.js
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
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
2020/02/10 PHP
javascript globalStorage类代码
2009/06/04 Javascript
浅谈Javascript鼠标和滚轮事件
2012/06/27 Javascript
JavaScript中的noscript元素属性位置及作用介绍
2013/04/11 Javascript
简单的Jquery遮罩层代码实例
2013/11/14 Javascript
angularJS 中input示例分享
2015/02/09 Javascript
JS实现判断碰撞的方法
2015/02/11 Javascript
教你使用javascript简单写一个页面模板引擎
2015/05/05 Javascript
详解JavaScript中getFullYear()方法的使用
2015/06/10 Javascript
jQuery实现首页图片淡入淡出效果的方法
2015/06/10 Javascript
javascript倒计时效果实现
2015/11/12 Javascript
jQuery解析json格式数据简单实例
2016/01/22 Javascript
JS中实现一个下载进度条及播放进度条的代码
2019/06/10 Javascript
微信小程序表单验证WxValidate的使用
2019/11/27 Javascript
js实现手表表盘时钟与圆周运动
2020/09/18 Javascript
Python守护线程用法实例
2017/06/23 Python
Python实现动态加载模块、类、函数的方法分析
2017/07/18 Python
Python中装饰器学习总结
2018/02/10 Python
Python实现的求解最小公倍数算法示例
2018/05/03 Python
python操作文件的参数整理
2019/06/11 Python
python3 深浅copy对比详解
2019/08/12 Python
python将字母转化为数字实例方法
2019/10/04 Python
python实现简单的五子棋游戏
2020/09/01 Python
h5实现获取用户地理定位的实例代码
2017/07/17 HTML / CSS
三只松鼠官方旗舰店:全网坚果销售第1
2017/11/25 全球购物
印度首选时尚目的地:Reliance Trends
2018/01/17 全球购物
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
2014年关于两会精神的心得体会
2014/03/17 职场文书
家教广告词
2014/03/19 职场文书
爱护花草树木的标语
2014/06/11 职场文书
2014年高数考试作弊检讨书
2014/12/14 职场文书
上市公司董事长岗位职责
2015/04/16 职场文书
2015年毕业实习工作总结
2015/05/29 职场文书
《狼王梦》读后感:可怜天下父母心
2019/11/01 职场文书
SQL SERVER存储过程用法详解
2022/02/24 SQL Server
Oracle锁表解决方法的详细记录
2022/06/05 Oracle