【问题标题】:Backbone.js model event not triggeringBackbone.js 模型事件未触发
【发布时间】:2011-11-04 02:26:37
【问题描述】:

我有以下视图文件:

var BucketTransferView = Backbone.View.extend(
{
initialize: function(args)
{
    _.bindAll(this);
    this.from_bucket = args.from_bucket;
    this.to_bucket = args.to_bucket;
},
events:
{
    'click input[type="submit"]' : 'handleSubmit',
},
render: function()
{
    $(this.el).html(ich.template_transfer_bucket(this.model.toJSON()));
    return this;
},
handleSubmit: function(e)
{
    that = this;

    this.model.save(
        {
            date: 1234567890,
            amount: this.$('#amount').val(),
            from_bucket_id: this.from_bucket.get('id'),
            to_bucket_id: this.to_bucket.get('id')
        },
        {
            success: function()
            {
                // recalculate all bucket balances
                window.app.model.buckets.trigger(
                    'refresh',
                    [that.to_bucket.get('id'), that.from_bucket.get('id')]
                );
            }
        }
    );
    $.colorbox.close();
}
});

我的 buckets 集合有这个刷新方法:

refresh: function(buckets)
{
    that = this;
    _.each(buckets, function(bucket)
    {
        that.get(bucket).fetch();
    });
}

我的问题是,当 fetch() 发生并更改集合的模型时,它不会触发其他具有相同模型的视图类中的更改事件。视图的模型有相同的cid,所以我认为它会触发。

这没有发生的原因是什么?

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    Fetch 将创建新的模型对象。任何与集合绑定的视图都应绑定到集合的重置事件并重新呈现自身。视图的模型仍然具有相同的 cid,因为它们持有对旧版本模型的引用。如果您查看 buckets 集合,它可能有不同的 cid。

    我的建议是在呈现桶的视图中,您应该呈现所有子视图并保留对这些视图的引用。然后在重置事件中,删除所有子视图并重新渲染它们。

    initialize: function()
    {
        this.collection.bind('reset', this.render);
        this._childViews = [];
    },
    
    render: function()
    {
        _(this._childViews).each(function(viewToRemove){
            view.remove();
        }, this);
    
        this.collection.each(function(model){
            var childView = new ChildView({
                model: model
            });
            this._childViews.push(childView);
        }, this)
    }
    

    我希望这对你有用,或者至少能让你朝着正确的方向前进。

    【讨论】:

    • 我猜你的意思是:this.collection.bind('reset', this.render); ?
    • 这与我呈现列表的方式不同(我绑定到集合上的 add 事件),但我现在将一个混合体拼凑在一起,它似乎可以工作。当列表中有大量项目时,看看这是否能正常工作会很有趣。
    • 另一种方法:如果您知道您只更改了 2 个模型(from_bucket 和 to_bucket),您可以仅对这 2 个模型调用 f​​etch,这不会创建新模型...然后您的视图绑定到那些应该检测到更改事件,您不必重新渲染所有视图
    • 我原来不就是这样吗?我打电话给collection.get(model.cid).fetch(),你解释说最终会得到一个新的cid,所以不会触发事件。我最终在整个集合上调用了 collection.fetch() 并重新渲染了整个东西。它目前有效,但我会研究一种更有效的方法,因为当列表超过少数项目时,我觉得这不会那么有效。
    猜你喜欢
    • 2012-04-16
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    • 2013-02-15
    • 2013-01-17
    相关资源
    最近更新 更多