【问题标题】:Bind and trigger backbone event to a specific view将主干事件绑定并触发到特定视图
【发布时间】:2012-12-18 06:08:20
【问题描述】:

我正在创建一个 ajax 上传组件,其中包含每个主干视图的进度条,这就是我的视图模板的样子。

<script id="view-template-dropped-file" type="text/html">
    <a><%=name %></a><span><%=fileSize%></span>
    <div class="ui-progress-bar">
        <div class="ui-progress"></div>
    </div>
</script>

当我将文件拖放到拖放区域时,我会像这样为每个文件创建一个视图

for (i = 0; i < files.length; i++) {
    var view = new DroppedFileView({
        model: new DroppedFile({
            name: files[i].name,
            fileSize: files[i].size
        })
    });
    var $li = view.render().$el;
    $('#droparea ul').append($li);
});

添加了一些文件的拖放区显示了每个文件的进度条。 http://cl.ly/Lf4v

现在当我按下上传时,我需要单独显示每个文件的进度。

我试图做的是像这样绑定到我的 DroppedFileView 中的一个事件

initialize: function() {
    var app = myapp.app;
    app.bind('showProgress', this._progress, this);
}

和 _progress 函数

_progress: function(percentComplete) {
    this.$el.find('.ui-progress').animateProgress((percentComplete * 100), function () { }, 2000);
}

这就是我从放置区域视图触发事件的方式

xhr: function () {
    var xhr = new window.XMLHttpRequest();
    xhr.upload.addEventListener("progress", function (e) {
        if (e.lengthComputable) {
            var percentComplete = e.loaded / e.total;
            app.trigger('showProgress', percentComplete);
        }
    }, false);
    return xhr;
}

这当然行不通,因为我在所有视图中收听相同的 showProgress 事件,这将导致所有进度条显示相同的进度。

那么,是否可以将事件绑定到指定视图,以便可以单独更新进度,或者事件不是一个好方法?

【问题讨论】:

    标签: backbone.js backbone-views backbone-events


    【解决方案1】:

    您可能需要考虑让DroppedFile 模型发出进度事件。因此,不要在app 上触发事件,而是在正在上传的模型实例上触发它。

    您的示例代码没有提到哪个类拥有xhr 方法,但在模型本身上定义它是有意义的。在这种情况下,事件触发是微不足道的:

    xhr: function () {
        var model = this;
        var xhr = new window.XMLHttpRequest();
        xhr.upload.addEventListener("progress", function (e) {
            if (e.lengthComputable) {
                var percentComplete = e.loaded / e.total;
                model.trigger('showProgress', percentComplete);
            }
        }, false);
        return xhr;
    }
    

    在视图构造函数中:

    initialize: function() {
        this.model.bind('showProgress', this._progress, this);
    }
    

    基于 cmets 编辑:

    即使您的视图结构比我上面假设的要复杂一点,在我看来,使用DroppedFile 模型作为事件发射器是可行的方法。如果一个DroppedFileView 代表DroppedFile,它应该反映它有意义的模型的状态。

    只需跟踪DropzoneView 中的模型,就像您现在使用DropzoneView.files 中的文件一样(或者不是如何)。您是想让实际的 AJAX 请求成为视图的责任还是将其重构为单个模型并不重要。

    【讨论】:

    • 实际上我有一个用于放置区域的视图和一个用于每个放置文件的视图,所以我猜模型上的触发器对我不起作用。我为此做了一个小提琴,展示了我正在处理的代码。 jsfiddle.net/eLLmW/66
    • @Marcus,更新了我的答案,对于 cmets 来说太长了。只是我的 0.02 美元
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多