Fork me on GitHub

第一次试讲的问题集中整理和归纳

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
      10
      var 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
      11
      var 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
5
fish.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
18
onDepositDetailClick: 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
      32
        var 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
4
callback: function ($view) {
this.acctInfoChildView = $view;
this.parentView.on('AcctId:change', this.loadAcctForm.bind(this));
}.bind(this)

A: bind(this)用于改变this指针指向的对象。