2.0.4 • Published 7 years ago

backbone-view v2.0.4

Weekly downloads
2
License
ISC
Repository
-
Last release
7 years ago

#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开始,如果是一个字符串,可选值为appendprepend,如果是一个函数,可自己设置子视图的位置,在函数里你可以得到view参数,表示子视图本身(注意,此时子视图已经和父视图关联,你只能操作jQuery元素来决定位置)。默认为'append'插入方式。
  • pos {String} 如果index是一个数字,而index存在一个子视图,那么pos决定被插入的视图是放到index视图的前面还是后面,可选的值为beforeafter
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参数,则返回所有匹配的子视图(数组),如果onetrue,则只返回第一个找到的子视图。

subViews()

返回一个数组包含所有子视图。

removeView(viewId, f)

删除子视图,该方法实际上是调用remove(f)方法。

empty()

删除所有子视图,该方法实际上是遍历所有子视图,然后调用remove()方法。

remove(f)

删除视图本身,将元素从DOM删除移除,停止所有监听器,解除和Model的绑定,如果本身存在子视图,则会清空(这也会导致子视图的remove操作),删除与父视图对象的引用关系。

  • f {boolean} 如果提供false,子视图只和父视图脱离关系,不会移除子视图的事件和HTML元素。

事件:子视图触发beforeRemoveremove事件,父视图触发removeView事件,如果视图本身有onBeforeRemoveSelfonRemoveSelf函数,则会被依次执行。

bindModel(options)

ModelView绑定,当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配置项

属性类型默认描述
propertystring, array希望监听的Model的属性,可以设置为一个数组,表示数组中任何一个属性发生改变时都会更新数据。
valueTypestring'text'设置属性值到jQuery元素上的方式,支持'text', 'val', 'attr', 'html', 'style'分别对应jQuery的方法。
methodstringModel的函数名,如果提供,则通过model[method]()来获取值,否则使用model.get(config.property)来获取值。
argsarray传给method的参数,method.call(model, args)
prefixstring如果提供,则会加在从Model获取到的值的前面。
suffixstring如果提供,则会加在从Model获取到的值的后面。
attrKeystring如果配置项valueType='attr',那么从model获取到的值将渲染在视图的这个属性上。
styleKeystring如果配置项valueType='style'$e.css(styleKey, value)

例子1:

<span data-binding="title"></span>

这是最简单的,当Modeltitle属性发生变化时,$(span).text(model.get('title'))

例子2:

<img 
	class="cover" 
	data-binding="{property:'coverUrl', method:'getCoverUrl', args:['2x'], valueType:'attr', attrKey:'src'}">

ModelcoverUrl属性发生变化时,调用ModelgetCoverUrl('2x')函数获取到值,然后将值设置到imgsrc属性上。

如何调用:

BaseView.extend({
	initialize: function() {
		this.$el = ...;//初始化$el
		var bindOptions = {}
		this.bindModel(bindOptions);
	}
});

函数的options参数配置项:

属性类型默认描述
modelBackbone.Model如果不提供,则绑定到视图自己的model上。
renderbooleantrue是否立刻触发一次数据渲染,这对于绑定后需要立即显示模型的数据到视图上是很有用的。

unbindModel()

解除对数据模型的监听。

bindModelProp(property, cb, trigger)

监听视图自身的Model的属性变化,当你调用unbindModel时会停止监听器。property是你希望监听的属性,你可以从cb回调函数中得到两个参数分别为modelnewValuetrigger表示是否立即触发一次属性值的更新,默认为true

该函数和bindModel函数不冲突,即使你绑定了模型,你依然可以继续绑定模型的属性。

bindCollection(collection, ViewClass, options)

绑定Backbone.Collection,监听addremove事件以做出相应的操作,如添加子视图,删除子视图。ViewClass是子视图的类,它应该是继承BaseView的且getViewId必须返回Model.id

当集合发生添加操作时,自动添加一个ViewClass到本容器中,集合发生移除操作时也会自动将该子视图从本视图中删除。

options

属性类型默认描述
addbool , functiontruetrue表示需要监听集合的add事件,false表示不需要,提供函数的话在做了默认的行为后会执行你的函数,你的函数可得到(view, collection, model)参数,view是实例化后的对象,且已添加到父视图中。
addPositionint , string , functionappend该参数会被传给addView的第二个参数,如果Model本身也有addPosition属性,会优先使用Model的。
removebool , functiontrueadd行为一样,监听的是集合的remove事件。
filterfunctionaddremove的默认行为执行之前执行的函数,返回false可以阻止后面的操作,用来过滤你不关心的Model,你可以得到参数(model, action)action的值为'add''remove'
dataobject用于传递给子视图构造函数的参数,请不要在里面定义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}里面的数字和后面参数的位置相对应。

2.0.4

7 years ago

2.0.3

7 years ago

2.0.2

7 years ago

2.0.1

7 years ago

2.0.0

7 years ago

1.0.6

7 years ago