Skip to content

Latest commit

 

History

History
182 lines (116 loc) · 5.44 KB

api.md

File metadata and controls

182 lines (116 loc) · 5.44 KB

#data.js

data.js在浏览器环境中默认占用全局变量Data,在模块化编程环境中,引用模块返回Data,返回的Data是一个数据中心+工厂函数,可直接将其作为一个数据中心使用,也可通过该函数创建新的数据中心。

//一下两种方式均可获取数据中心的实例
var D = Data();
var D = new Data();

//有一个数据中心,与上面的D无关系
var F = new Data();

//在实例化的数据中心上操作
F.set(***);

//在默认的数据中心上操作
Data.set(***);

##noConflict

此函数会在以原始方式在浏览器中引入是存在,用来释放Data占用的全局变量Data。同时返回Data。

  • return {Function} Data

demo

var D = Data.noConflict();//释放Data,并赋值给D

##version

获取data.js的版本号,字符串,仅在Data上存在。

console.log(Data.version);//0.1.0
console.log(Data().version);//undefined

##has

判断Data中是否存在,指定的数据。

  • key {String} 要判断的键,点号是分隔符,用来分隔对象层次
  • return {Bollean} 是否包含指定键值

demo

Data.has(key);//返回true或false

##get*

从Data中获取指定的键值。

  • key {String} 要获取的键
  • return {val} 返回与键值对应的数据,若键值的上游不存在,会返回undefined或null

demo

Data.get('a');//undefined
Data.get('a.b.c')//undefined

**注:**此处获取的是Data中数据的深拷贝,即get接口返回的数据是Data中对应数据的一份深拷贝。之所以牺牲性能,这样设计是因为深拷贝能避免很多难以预知的bug。

下面是深拷贝,浅拷贝和引用的区别:

//深拷贝
var a = Data.get('a');//若a为{b:{c:1}}
a.b.c= 2;//此处更改不会影像Data中的数据
Data.get('a.b.c')//此处输出1

//浅拷贝
var a = Data.get('a');//若a为{b:{c:1}}
a.b.c= 2;
Data.get('a.b.c')//此处输出2

//仅返回引用
var a = Data.get('a');//若a为{b:{c:1}}
a.b = 1;
Data.get('a.b')//此处输出1

##set*

向Data中放入数据。若已存在,则是扩展当前数据,不会重新赋值(对于数组或对象,对于其他类型值会覆盖)。

  • key {String} 放入Data中数据的键值
  • val {val} [可选] 放入Data中的数据
  • return {Bollean} 是否添加成功

传入key + val 和 传入 {key: val}的方式等价,可以选择自己喜欢的方式,键值的方式更清晰,作者推荐前一种,记住只使用同一种方式会让事情变得简单。

demo

//传入值类型
D.set('a', 1);
D.get('a');//1

//传入引用类型
D.set('a', {b: 1});
D.get('a.b');//1

D.set('a.b.c', 1);
D.set('a', {b: {c: 1}}});//这两种功能一样

###key key值是Data的基石,key是一个字符串,Data的key支持任何utf-8编码的字符,js支持的就可以

  • 字母 abc
  • 数字 123
  • 特殊字符 _-+$;'"...
  • 甚至是汉字 颜海镜

Data都可以完美支持,同时key还有类似对象属性的特性,a.b.c是获取a下的b下的c,其中.号是分隔符,可以想像成js中的对象(其实Data内部确实是按对象处理)。

D.set('a', {});
D.set('a.b', 1);
D.set('a.c', [1]);
D.set('a.1.1', 1);//此处会创建数组

D.get('a')的输出如下:

{
	1: [1],
	b:1,
	c:[undefined ,1]
}

Data可以将传入的键,智能转换为对应的空间,支持对象和数组。

##sub* sub方法是Data的核心方法,用来订阅消息,订阅指定键值的指定事件,在对应的值发生变化时,会得到通知(当传入对象和数组时,消息会下发到其子元素)。

  • type {String} 订阅消息的类型 (可选值:set, add, update, delete 分别代表 设置,添加,更新,删除,其中set是通用类型,其他三个为细分类型,并且互斥)
  • key {String} 订阅消息的键值
  • callback {Function} 消息接受函数
  • return {Number} 消息的同意id用于取消订阅事件用

demo

D.sub('set', 'a', function (e) {console.log(e)});

D.set('a', 1);//a值更新,会调用回调函数

###e

  • type {String} 消息的类型
  • key {String} 消息的建
  • data {val} 设置的值

##unsub

取消订阅的消息。

  • type {String} 取消订阅消息的类型 (可选值:set, add, update, delete 分别代表 设置,添加,更新,删除,其中set是通用类型,其他三个为细分类型,并且互斥)
  • key {String} 取消订阅消息的键值
  • id {Number} [可选] sub是返回的消息的id
  • return {Bollean} 是否取消成功

若id为空则会删除所有对应键值和类型的所有事件。

demo

var id = D.sub('set', 'a', function (e) {console.log(e)});

D.set('a', 1);//a值更新,会调用回调函数

D.unsub('set', 'a', id);

D.set('a', 1);//不会在收到通知

##注意事项

由于Data设计之初希望支持跨平台,所以要支持ecmascript类型数据,Data希望放入的是数据,期望的是原生数据,支持 Number,Bollean,String,Object,null,undefined,Array。对于Object和Array会是其深拷贝值,并且会创造层级。

对于其他类型对象js都默认为值类型,如dom节点,仅简单赋值其引用,所以消息无法下发到dom的子元素上,但get接口可以取到其子元素。其他类型对象还包括:

  • window
  • document
  • dom
  • dom list
  • node list

请不要将复杂对象和引用自身的对象放入Data中,会造成性能的严重下降,和不可预知的问题。复杂对象包括如下:

  • jquery对象

建议放入原生数据,对于jquery对象可传入其查询字符串。