Q&A
Q: 绑定事件何时销毁,会不会触发两次。
涉及代码:1
2
3
4//账户界面
this.trigger('AcctId:change', this.acctList.get(this.currentAcctId));
//账户详情界面
this.parentView.on('AcctId:change', this.loadAcctForm.bind(this));
A:绑定一个事件,调用多次会触发多次;一个事件绑定多次,一次调用都会触发。事件调用off方法销毁。
这个是关于Backbone的事件管理的问题,Backbone的Events是其很重要的内容之一,因为Events是Backbone中所有其它模块的基类,无论是Model、Collection、View还是Router和History,都继承了Events中的方法。
Events提供的事件管理相关的方法,包括on、off和trigger(类似于JQuery的bind、unbind和trigger)。
on:将一个函数绑定到对象的某个事件中
- on( event, callback, [context] )。event:事件名称;callback:回调函数;context:给回调函数提供一个上下文,默认以该对象为函数上下文。
- 在对象上绑定一个callback回调函数。只要event触发,该回调函数就会调用。
- 如果你的页面含有大量的不同事件,我们约定使用冒号来为事件添加命名空间,也可以同时绑定多个事件,事件用空格分隔。
- 如果监听的是”all”事件,那么任何事件的触发都会触发该回调函数,回调函数的第一个参数会传递该事件的名称。
off:移除全局事件监听。移除对象先前绑定的callback函数。
- off( [event], [callback], [context] )。参数含义与on一致。
- 如果没有指定context(上下文),所有上下文下的这个回调函数将被移除。
- 如果没有指定callback,所有绑定这个事件回调函数将被移除。
- 如果没有指定event,所有事件的回调函数会被移除。
- trigger:触发对象的某个事件。
- trigger( event, [args] )。event:事件名称;其余参数将会传递到触发事件的回调函数里,作为其参数。
关于事件的绑定和触发次数的问题,这里通过示例代码说一下:
给对象model绑定一个事件时,trigger调用多次可多次触发。
1
2
3
4
5
6
7
8
9//创建一个Model对象
var model = new Backbone.Model();
// 在model对象中向自定义事件event绑定函数
model.on('event', function (p1, p2) {
console.log('触发1' + p1 + p2);
});
// 触发event事件,将调用上面绑定的函数
model.trigger('event', 'value1', 'value2');
model.trigger('event', 'value3', 'value4');1
2
3//输出
触发1value1value2
触发1value3value4给一个对象绑定多个事件时,调用trigger会同时触发。
1
2
3
4
5
6
7
8
9
10var model = new Backbone.Model();
// 在model对象中向自定义事件event绑定两个函数
model.on('event', function (p1, p2) {
console.log('触发1' + p1 + p2);
});
model.on('event', function(p1, p2) {
console.log('触发2'+p1+p2);
});
// 触发event事件,将调用上面绑定的两个函数
model.trigger('event', 'value1', 'value2');1
2
3//输出
触发1value1value2
触发2value1value2关于移除事件后的再次触发。已经off后的函数不会再触发。
这里触发事件没有传递函数参数,所以输出未定义。1
2
3
4
5
6
7
8
9
10
11var model = new Backbone.Model();
// 在model对象中向自定义事件event绑定两个函数
model.on('event', function (p1, p2) {
console.log('触发1' + p1 + p2);
});
// 移除event事件中绑定的所有方法
model.off('event').on('event', function (p1, p2) {
console.log('移除后触发' + p1 + p2);
});
// 触发event事件,但不会执行已被移除的函数
model.trigger('event');1
2//输出
移除后触发undefinedundefined
注:事件的触发顺序和绑定顺序一致。all事件总会在其它事件中的监听函数都执行完毕之后触发。
- 可参考:https://blog.csdn.net/likun557/article/details/53169357
Q: fish.each和$.each的区别
A:
两者回调函数参数不同;后者可以使用return false退出循环而前者不可以。
涉及代码:1
2
3
4
5fish.each(this.paymentViewSelectors, function (selector) {
var $view = this.getView(selector);
$view && $view.$form && $view.$form.form('clear');
$view && $view.$grid && $view.$grid.grid('clearData');
}.bind(this))
具体内容单独写了篇来介绍,详见:关于fish.each()、$(selector).each()和$.each()的各自含义与区别
Q: document.body.clientWidth含义
涉及代码:width和height来自表格详情按钮点击的popView方法。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18onDepositDetailClick: function () {
var rowData = this.$depositGrid.grid('getSelection');
var id = this.$depositGrid.grid('getRowid', rowData);
rowData = this.$depositGrid.grid('getRowData', id);
fish.popupView({
url: 'modules/order/order-entry/views/popwin/DepositDetailPopView',
viewOption: {
"subsId": rowData.subsId,
"depositTypeId": rowData.depositTypeId,
"accNbr": rowData.accNbr
},
width: document.body.clientWidth * 0.85,
height: document.body.clientHeight * 0.8,
close: function () {
}.bind(this)
});
},
A:
网页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight。
- 关于document对象:
- 每个载入浏览器的 HTML 文档都会成为 Document 对象。Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。(Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问。)
- 其中,body是document的属性之一,提供对 <body> 元素的直接访问。
- 可参考:http://www.w3school.com.cn/jsref/dom_obj_document.asp
document.body.clientHeight 是获取body元素的高度,它有默认高度,是随内容高度而撑开,是height:auto;
相比之下,document.documentElement.clientHeight 是获取文档的高度,它因为是有默认高度的,等于窗口高度,就是height:100%;
body元素又是一个块级元素,默认宽度100%。
Q: Fish.View的$el属性
A: $el:false的含义。
涉及内容:FISH框架视图View的加载。
来自FISHwiki:
- 关于视图加载的定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32var MyView = fish.View.extend({
// 视图 Dom 元素
el: '#app',
// 视图模板函数
template: fish.compile('<p>{{name}}</p>'),
// 填充模板数据
serialize: {
name: 'Lilei'
},
// 视图事件处理
events: {
'click': 'onClick'
},
// 视图初始化
initialize: function() {
// do something
console.log('enter initialize...');
},
// 视图渲染结束处理
afterRender: function() {
// do something
console.log('enter afterRender...');
},
// 视图移除处理
cleanup: function() {
// do something
console.log('enter cleanup...');
},
onClick: function() {
alert('click');
}
});
- 关于视图加载的定义:
关于视图属性:
- 其中el是视图的Dom元素,默认是 <div></div>,所以如果不设置时,视图创建出来会在模板外包装一层 div 节点。
- 设置为选择器字符串,表示模板内容插入到对应选择器里 (eg: el: ‘#myDiv’)。
- 设置为 false ,表示以模板内容为视图 Dom 元素。
- 可参考:http://fish.ztesoft.com/fish-desktop/guide/View-Definition.html
Q: bind(this)的作用
涉及代码:1
2
3
4callback: function ($view) {
this.acctInfoChildView = $view;
this.parentView.on('AcctId:change', this.loadAcctForm.bind(this));
}.bind(this)
A: bind(this)用于改变this指针指向的对象。
- 这里涉及到this,以及apply、call、bind方法。单独写了一篇文章说明一下这个问题。详见:关于对this的理解,以及bind()、apply()和call()的关系