配置项
配置项类实例化时的初始配置,决定对象的初始值,我们看一下示例:
<pre class="prettyprint linenums" style="padding: 8px; background-color: rgb(247, 247, 249); border: 1px solid rgb(225, 225, 232); margin-top: 8px; box-shadow: rgb(251, 251, 252) 40px 0px 0px inset, rgb(236, 236, 240) 41px 0px 0px inset; color: rgb(51, 51, 51); font-size: 12px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<script>
function A (a,b){
}
var a = new A('a,','b'); //配置项作为独立的参数传入
function B (config){
}
var b = new B({a : 'a',b : 'b'}); //配置项作为键值对的形式传入
</script>
</pre>
我们在这里约定,BUI中的所有控件的配置项全部按照键值对的形式传入,也就是说所有的类实例化时只需要传入一个参数。
属性
属性一般是指对象的某个性质,对于javascript对象而言可以是对象、方法、直接量。由于javascript对象对于成员不存在访问控制,所以对成员的访问和设置没法进行控制,属性发生改变时也无法做出对应的相应。如下示例:
<pre class="prettyprint linenums" style="padding: 8px; background-color: rgb(247, 247, 249); border: 1px solid rgb(225, 225, 232); margin-top: 8px; box-shadow: rgb(251, 251, 252) 40px 0px 0px inset, rgb(236, 236, 240) 41px 0px 0px inset; color: rgb(51, 51, 51); font-size: 12px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<script>
function A (a){
this.a = a;
this.setA = function(a){
this.a = a;
//do something
//log(a);
}
}
var obj = new A('a value');
//如果我想伴随着a 值的改变做些处理
obj.setA('new a value');
//但是由于对象不存在访问控制
obj.a = 'new b value'; //此时不会执行对应的操作
</script>
</pre>
所以我们需要这样一种属性:
- 能够对属性的设置和访问做限制
- 属性的改变能够通知其他对象
- 配置项通过初始化能够转成属性
BUI.Base类
所以我们使用了BUI.Base
类,它拥有以下功能:
- 有get和set方法用于获取和设置属性,不能直接通过“.”,“[]”操作符修改属性值。
- 属性值发生改变时触发
beforeXxxChange
和afterXxxChange
事件,其中属性名是xxx
- 构造函数的配置项可以转换成属性值
属性的细节和使用接下来我们会详细的讲解,所有需要使用属性的类,继承BUI.Base类即可
<pre class="prettyprint linenums" style="padding: 8px; background-color: rgb(247, 247, 249); border: 1px solid rgb(225, 225, 232); margin-top: 8px; box-shadow: rgb(251, 251, 252) 40px 0px 0px inset, rgb(236, 236, 240) 41px 0px 0px inset; color: rgb(51, 51, 51); font-size: 12px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<script>
function A (config){
A.superclass.constructor.call(this,config)
}
BUI.extend(A,BUI.Base); //继承属性类
A.ATTRS = { //在ATTRS上定义属性
a : {
value : 'a' //默认值
},
b : {
}
};
var a = new A({ a : 'initial a',b : 'b'}); //创建A 的实例
a.get('a'); //initial a
a.set('a','new a'); //new a
b.get('b'); //b
a.set('c','c');
a.get('c'); //c
</script>
</pre>
- 声明新的类A,并在构造函数里调用父类的构造函数
- 继承
BUI.Base
使用BUI.extend
方法 - 声明属性值,每个属性是一个对象,
value
是默认值,属性的定义下面有更详细的介绍 - 创建A的实例a,传递配置项,配置项会转变成属性值
- 通过A的示例获取,设置定义的属性,会触发(beforeXxxChange,afterXxxChange)事件,例如name 属性会触发(beforeNameChange,afterNameChange)
- 设置未定义的属性,依然会生效,但是不会有默认值,依然会触发事件
属性的定义
上面的示例说明了如何定义一个属性,和如何设置默认值value
,接下来我们来看属性还支持哪些功能
<pre class="prettyprint linenums" style="padding: 8px; background-color: rgb(247, 247, 249); border: 1px solid rgb(225, 225, 232); margin-top: 8px; box-shadow: rgb(251, 251, 252) 40px 0px 0px inset, rgb(236, 236, 240) 41px 0px 0px inset; color: rgb(51, 51, 51); font-size: 12px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<script>
function A (config){
A.superclass.constructor.call(this,config)
}
BUI.extend(A,BUI.Base); //继承属性类
A.ATTRS = { //在ATTRS上定义属性
a : {
value : 'a' //默认值
},
b : {
getter : function(v){ //获取函数,v是当前属性设置的值,返回值为 a.get('b')的值
return v * 2;
},
setter : function(v){
return parseInt(v);
}
},
c : {
valueFn : function(){ //在第一次调用此属性是执行此函数,并作为属性的值使用,只执行一次
return this.get('a') + this.get('b');
}
},
d : {
value : 'd', //如果value和valueFn同时存在,则以value优先
valueFn : function(){
return this.get('a');
}
}
};
var a = new A({a : 'a1',b : '2'}); //{a :'a1',b : '2'}
a.get('a'); //a1
a.get('b'); //2 * 2 = 4
a.get('c'); //a1 + 4 = a14
a.get('d'); //a1
</script>
</pre>
上面的示例说明了属性的具体用法,以及内部的成员的含义:
- value : 属性的默认值
- getter : 获取属性时执行,并以getter的返回结果为准
- setter : 设置属性时执行,以setter的返回值为准
- valueFn : 属性第一次获取时执行,之后作为value来使用,如果同时定义了value ,不执行此函数。
属性图示
下图说明了属性的执行过程
Base类有2个私有字段和一个静态字段:
- ATTRS:是在类定义时指定的属性定义
- __attrs :存放类和从父类继承来的属性定义
- __attrVals:存放通过配置项设置的值或者通过set方法设置的值
属性获取
- 获取属性值,先查找__attrVals中是否存在值,如果存在通过getter(如果存在)格式化返回;
- 如果不存在查看__attrs里对应的属性,查看是否存在value,存在通过getter格式化返回
- 如果不存在,查看valueFn,执行完valueFn后,将返回值替换为value,通过getter格式化返回
属性设置
- 设置值,先通过setter(如果存在)格式化
- 触发beforeXxxChange事件
- 覆盖__attrVals中的值
- 触发afterXxxChange事件
Xxx
代表属性名,首写字母大写,如: name => beforeNameChange,afterNameChange
属性类的API
BUI.Base
继承自BUI.Obeservable
,继承来的属性和方法,请查看BUI的方法和事件
下面只是简单的列表,未显示从父类继承来的方法,详细信息请查看API文档
下一步学习
BUI的配置和属性是所有控件的一个基础章节,接下来继续学习BUI的方法和事件,你可以去看一下如何组织模块CMD组织模块,然后进入到BUI控件编写的学习中。