backbone-view
v2.0.4
Published
A library extend from Backbone.
Downloads
1
Readme
#backbone-view
[TOC]
##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}
里面的数字和后面参数的位置相对应。