backbone-view v2.0.4
#backbone-view
##Install
npm install backbone-view##How to use
/*before
<div id="my-view">
<ul></ul>
</div>
*/
const BaseView = require('backbone-view');
var ParentView = BaseView.extend({
initialize: function() {
this.$el = $('#my-view');
//this.$el = $('<div>');
},
getViewContainer: function() {
return this.$('ul');
}
});
var SonView = BaseView.extend({
initialize: function(id, name) {
this.id = id;
this.$el = $('<li>').text(name);
},
getViewId: function() {
return this.id;
}
});
var pv = new ParentView();
pv.addView(new SonView(1, 'one'));
pv.addView(new SonView(2, 'two'));
pv.addView(new SonView(3, 'three'));
/*after
<div id="my-view">
<ul>
<li view-id="1">one</li>
<li view-id="2">two</li>
<li view-id="3">three</li>
</ul>
</div>
*/##Introduction
这是对Backbone.View的增强,增加了许多有用的工具函数,主要目的在于将view和view之间能够形成关系,如可以添加子视图。你的自定义视图应该继承该视图来获得便捷的工具。
BackboneView总是建立在你的$el已经初始化完成的前提下,也就是你总是应该在你的initialize函数里尽快初始化好$el属性,因为BackboneView总是和一个$html元素有关。
API
getViewContainer()
定义你的视图的哪部分作为子视图的容器,默认为$el,子类可以覆盖该函数来返回自己的容器元素。
getViewId()
当一个视图被作为子视图添加到父视图中时,会自动为子视图的$el元素设置一个view-id的属性,这个属性的值就是使用getViewId来获取的,默认的,如果你的视图和一个Model绑定,那么会返回这个Model.id,否则随机产生一个id。你可以覆盖该函数来自己决定视图ID是什么。
如果你想从$el元素中获取到viewId,可以使用BaseView.processViewId($e)来获得,而不要硬编码$(e).attr('view-id')。
addView(view, index, pos)
添加子视图,view必须也是BackboneView的子类,否则会抛出异常,如果view已经存在其他父视图中了也会抛出异常。
view{BackboneView} 子视图。index{int | String | function} 决定子视图在父视图中的位置(文档的位置),如果是一个数字,表示子元素的位置,从0开始,如果是一个字符串,可选值为append或prepend,如果是一个函数,可自己设置子视图的位置,在函数里你可以得到view参数,表示子视图本身(注意,此时子视图已经和父视图关联,你只能操作jQuery元素来决定位置)。默认为'append'插入方式。pos{String} 如果index是一个数字,而index存在一个子视图,那么pos决定被插入的视图是放到index视图的前面还是后面,可选的值为before或after。
p.addView(view, 2);
p.addView(view, 'prepend');
p.addView(view, function(view) {
//自己处理插入
});
p.addView(view, 2, 'after');view添加完毕后,子视图会触发一个add事件,而父视图会触发一个addView事件,参数和addView函数一样。
var p = ...;
p.on('addView', function(view, index) {
//view is subView
})
p.addView(subView);get()
获取$el属性。
getView(viewId)
获取子视图,如果找不到则返回null。
getParent()
firstView()
获取第一个子视图,没有则返回null。
lastView()
获取最后一个子视图,没有则返回null。
prevView()
获取同级视图的上一个视图,没有则返回null。
nextView()
获取同级视图的下一个视图,没有则返回null。
setZIndex(index)
设置视图的z轴层级。
getZIndex()
获取视图的z轴层级。
afterOf(targetView)
将自己放到targetView的后面。
beforeOf(targetView)
将自己放到targetView的前面。
getViewCount()
获取子视图的数量。
sort(viewProperty, desc)
排序子视图,
如果viewProperty是一个字符串,表示视图的属性名,如果是一个函数,你需要返回一个值,你从函数中可以得到子视图对象,默认是升序,如果你提供desc并且传'desc'的话则降序。
each(cb)
遍历子视图。
cb{Function}view{BackboneView} 子视图。index{int} 子视图在文档结构中的位置,从0开始。
cb函数返回false可以立即结束遍历。
view.each(function(subView, index) {
//this == view
})findView(properties, one)
properties是一个简单对象,用来查找匹配的子视图,当子视图的属性都和properties一样则返回,如果你不提供one参数,则返回所有匹配的子视图(数组),如果one为true,则只返回第一个找到的子视图。
subViews()
返回一个数组包含所有子视图。
removeView(viewId, f)
删除子视图,该方法实际上是调用remove(f)方法。
empty()
删除所有子视图,该方法实际上是遍历所有子视图,然后调用remove()方法。
remove(f)
删除视图本身,将元素从DOM删除移除,停止所有监听器,解除和Model的绑定,如果本身存在子视图,则会清空(这也会导致子视图的remove操作),删除与父视图对象的引用关系。
f{boolean} 如果提供false,子视图只和父视图脱离关系,不会移除子视图的事件和HTML元素。
事件:子视图触发beforeRemove和remove事件,父视图触发removeView事件,如果视图本身有onBeforeRemoveSelf和onRemoveSelf函数,则会被依次执行。
bindModel(options)
将Model和View绑定,当Model的属性发生改变时可以立即更新View的数据。你必须先初始化$el才能调用此函数,在删除视图之前你必须先unbindModel()。当你绑定Model后,后面要从View中剥离Model前一定要unbindModel()。bindModel函数已经先为你做了unbindModel。
用法:
html结构:你必须使用一个容器来包裹着含有data-binding属性的元素。
<div>
<span data-binding="name"></span>
<span data-binding="{property:'age'}"></span>
<span data-binding="{property:'birthday', method:'getBirth'}"></span>
<span data-binding="{property:['price', 'count'], method:'getTotal'}"></span>
</div>html配置项
| 属性 | 类型 | 默认 | 描述 |
|---|---|---|---|
| property | string, array | 希望监听的Model的属性,可以设置为一个数组,表示数组中任何一个属性发生改变时都会更新数据。 | |
| valueType | string | 'text' | 设置属性值到jQuery元素上的方式,支持'text', 'val', 'attr', 'html', 'style'分别对应jQuery的方法。 |
| method | string | Model的函数名,如果提供,则通过model[method]()来获取值,否则使用model.get(config.property)来获取值。 | |
| args | array | 传给method的参数,method.call(model, args)。 | |
| prefix | string | 如果提供,则会加在从Model获取到的值的前面。 | |
| suffix | string | 如果提供,则会加在从Model获取到的值的后面。 | |
| attrKey | string | 如果配置项valueType='attr',那么从model获取到的值将渲染在视图的这个属性上。 | |
| styleKey | string | 如果配置项valueType='style',$e.css(styleKey, value)。 |
例子1:
<span data-binding="title"></span>这是最简单的,当Model的title属性发生变化时,$(span).text(model.get('title'))。
例子2:
<img
class="cover"
data-binding="{property:'coverUrl', method:'getCoverUrl', args:['2x'], valueType:'attr', attrKey:'src'}">当Model的coverUrl属性发生变化时,调用Model的getCoverUrl('2x')函数获取到值,然后将值设置到img的src属性上。
如何调用:
BaseView.extend({
initialize: function() {
this.$el = ...;//初始化$el
var bindOptions = {}
this.bindModel(bindOptions);
}
});函数的options参数配置项:
| 属性 | 类型 | 默认 | 描述 |
|---|---|---|---|
| model | Backbone.Model | 如果不提供,则绑定到视图自己的model上。 | |
| render | boolean | true | 是否立刻触发一次数据渲染,这对于绑定后需要立即显示模型的数据到视图上是很有用的。 |
unbindModel()
解除对数据模型的监听。
bindModelProp(property, cb, trigger)
监听视图自身的Model的属性变化,当你调用unbindModel时会停止监听器。property是你希望监听的属性,你可以从cb回调函数中得到两个参数分别为model和newValue,trigger表示是否立即触发一次属性值的更新,默认为true。
该函数和bindModel函数不冲突,即使你绑定了模型,你依然可以继续绑定模型的属性。
bindCollection(collection, ViewClass, options)
绑定Backbone.Collection,监听add和remove事件以做出相应的操作,如添加子视图,删除子视图。ViewClass是子视图的类,它应该是继承BaseView的且getViewId必须返回Model.id。
当集合发生添加操作时,自动添加一个ViewClass到本容器中,集合发生移除操作时也会自动将该子视图从本视图中删除。
options
| 属性 | 类型 | 默认 | 描述 |
|---|---|---|---|
| add | bool , function | true | true表示需要监听集合的add事件,false表示不需要,提供函数的话在做了默认的行为后会执行你的函数,你的函数可得到(view, collection, model)参数,view是实例化后的对象,且已添加到父视图中。 |
| addPosition | int , string , function | append | 该参数会被传给addView的第二个参数,如果Model本身也有addPosition属性,会优先使用Model的。 |
| remove | bool , function | true | 和add行为一样,监听的是集合的remove事件。 |
| filter | function | 在add和remove的默认行为执行之前执行的函数,返回false可以阻止后面的操作,用来过滤你不关心的Model,你可以得到参数(model, action),action的值为'add'或'remove'。 | |
| data | object | 用于传递给子视图构造函数的参数,请不要在里面定义model配置项,因为已经被占用。 |
var UserView = BaseView.extend({
...
});
BaseView.extend({
initialize: function() {
this.bindCollection(collection, UserView, {
add: function(view) {
//这里可以有机会对新添加的子视图做修改
this.listenTo(view, 'error', function() {
})
},
filter: function(model, action) {
//小于16岁的用户不显示在视图上,但注意,模型还是会在集合中
if(action == 'add' && model.get('age') < 16) return false;
else return true;
}
})
}
})unbindCollection(collection)
bindEvents(options, context, selectorContext)
使用配置的方式为对象绑定事件,主要是为了解决Backbone的events配置问题,如果$el是在initialize中初始化的话,events配置就无意义了。
options{PlainObject}
{
'property': { 'event1': Callback, 'event2': Callback },
'$ selector': { 'event1': Callback, 'event2': Callback },
'event property': Callback,
'event $ selector': Callback
}Callback可以是一个字符串或是一个函数,如果是字符串,则表示当前View的方法名,如果是一个函数,其this会被指向为当前View。
property表示当前View的属性,这个属性只能是一个jQuery元素或是Backbone.View。
$是固定值,如果加了$,那么它的后面的selector就是一个查询器,会被这样this.$(selector)用来查询jQuery元素。
event,event1,event2,eventX是事件名。
例子:
BaseView.extend({
initialize: function() {
var view = this;
view.bindEvents({
'uploadView': {
'start': 'onUploadViewStart',
'stop': function() {
//this == view
},
'complete': function() {}
},
'$ button.upload': {
'click': 'onUploadClick'
},
'upload uploadView': 'onUploadViewUpload',
'click $ button.stop': 'onStop'
})
}
})context{Object} 配置中Callback的上下文,默认是视图本身。selectorContext{jQuery} 当配置是'$'开头时,此配置是查询符的上下文,如:version 2.0.4
this.bindEvents({
'click $ button': 'onClick'//button会限制在.toolbar下查找
}, null, this.jq('.toolbar'));cache()
version 2.0.3
将视图本身缓存,然后通过View.findView(id)来获取。
static findView(id)
version 2.0.3
此函数是静态的,当你使用cache函数缓存本身后,你可以使用此函数来获取它。
renderModel(options)
version 2.0.3
和bindModel一样,但是本函数不监听数据变化,只渲染一次数据。
show()
version 2.0.3
hide()
version 2.0.3
jq(selector, ...)
version 2.0.3
与$()函数一样,查找视图下的元素,本函数增加了占位符,如:
view.jq('.{0}[data="{1}"]', 'btn', 'action')
//.btn[data="action"]{n}里面的数字和后面参数的位置相对应。