Backbone.js经验两则

使用HTML5,实现从桌面拖拽到网页

使用HTML5新增加的API,可以很方便的实现拖拽, 包括从桌面拖拽到网页上(部分浏览器比如Chrome还可以把东西从网页拖拽到桌面),这个操作不在今天的讨论之内,可以参考:NATIVE HTML5 DRAG AND DROP这篇文章,讲得足够详细了。

当我试图在Backbone框架上使用这个功能的时候,问题出现了。开始我没多想,直接这么写的:

var myView = Backbone.View.extend({
  events: {
    "drop img": "img_dropHandler"
  },
  img_dropHandler: function (event) {
    var reader = new FileReader();
    var img = event.target;
    reader.onload = function (event) {
      $(img).attr('src', event.target.result);
    }
    result.readAsDataURL(event.dataTransfer.files[0]);
  }
});

结果运行时提示我,event对象没有dataTransfer属性。我用的是最新版本的Chrome,理应是对HTML5支持最好的,而且文中也说代码在Firefox和Chrome下运行通过。后来检查了一下event,发现是f.Event,似乎原本应该是MouseEvent或者Event什么的。于是我把属性展开,看到了originalEvent这个属性,是MouseEvent;再展开originalEvent,就看到了dataTransfer属性,里面有期望中的所有属性。看来是Backbone并没有直接使用原始事件,而是封装了一层再广播。(更正)事件代理是通过jQuery来做的,jQuery在这里把原始事件封装了一层再进行转播,导致原始事件的属性没有完全复制。解决方法很简单,多写几个字母就行了:

// 其它地方都一样
result.readAsDataURL(event.originalEvent.dataTransfer.files[0]);

Model中数组的处理

先看一段代码:

var ModelClass = Backbone.Model.extend({
  defaults: {
    contents: []
  }
});
var model1 = new ModelClass();
var arr = model1.get('contents');
arr[0] = 'haha';
var model2 = new ModelClass();
console.log(model2.get('contents'));

大家猜猜结果是什么?竟然是“[‘haha’]”!这个我只能认为是Backbone.js的bug了。解决方法是先复制一个数组,对数据操作后再赋值回去,如下:

var model1 = new ModelClass();
var arr = model1.get('contents').concat();
arr[0] = 'haha';
model1.set('contents', arr);

如果您觉得文章内容对您有用,不妨支持我创作更多有价值的分享:


已发布

分类

来自

评论

《“Backbone.js经验两则”》 有 3 条评论

  1. […] Backbone.js经验两则 […]

  2. rainbow702 的头像

    defaults: { contents: [] }
    如果按照上面这么写的话,是每个该Model的实例都共享这一个数组。
    你换成以下这个试试:
    defaults: function(){ return {contents:[]}}
    :wink:

    1. meathill 的头像

      嗯,有道理。
      回头我试一下。

欢迎吐槽,共同进步

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据