【问题标题】:Backbone.js: Custom subscribing and publishing custom event between views / modelsBackbone.js:视图/模型之间的自定义订阅和发布自定义事件
【发布时间】:2012-10-10 12:02:59
【问题描述】:

这是我的情况:我使用 jQuery.Forms 来进行 ajax 调用,而不是提交表单。当 ajax 调用开始并返回时,我需要各种模型/视图来响应这些事件(模型使用从调用返回的数据进行更新,某些控件被禁用然后启用等等)。

我在视图中映射了表单。我如何才能从视图中触发自定义“formSubmitting”“formSubmitted (with data)”并让任意数量的模型/视图响应这些事件?使用 Backbone.js 执行此操作的最惯用方式是什么?

编辑:

这就是我想要做的:

    window.UploaderView = Backbone.View.extend({
        initialize: function() {
            this.setElement(this.options.base_div);
            this.$el.find('form').ajaxForm({
                beforeSubmit: function() {
                    this.trigger('ajax-calling');
                },
                success: function(responseJSON) {
                    this.trigger('ajax-called', responseJSON);
                },
                dataType: 'json,'
            });
        },
    });

    var update_uploader = new window.UploaderView({
        base_div: $('#update-upload-action'),
    });

    var trigged = new window.UploaderView({
        parent_view: update_uploader,
        initialize: function() {
            this.options.parent_view.on('ajax-calling', function() {
                alert('calling!');
            });
        },
    });    

但这不起作用(不显示警报消息)。

谢谢

【问题讨论】:

  • 我认为那里的同步存在一些问题,如果尚未创建 Trigged 视图并且 UploaderView ajax 已返回成功,则侦听器尚未到位,不会发生任何事情。 t ?

标签: javascript events javascript-events backbone.js


【解决方案1】:

当您创建新的 window.UploaderView 实例时,您的 initialize 函数永远不会执行,而是放置在视图的选项中(参见 Backbone.js View construction documentation)。

您需要的是一个事件总线,从Backbone.Events 继承的单个对象,并且可用于您的所有视图/模型:

var eventBus = _.clone(Backbone.Events);

window.UploaderView = Backbone.View.extend({
    initialize: function() {
        this.setElement(this.options.base_div);
        this.$el.find('form').ajaxForm({
            beforeSubmit: function() {
                eventBus.trigger('ajax-calling');
            },
            success: function(responseJSON) {
                eventBus.trigger('ajax-called', responseJSON);
            },
            dataType: 'json,'
        });
    },
});

window.AnotherView = Backbone.View.extend({
    initialize: function() {
        eventBus.on('ajax-calling', this.ajaxCallingHandler);
    },
});

window.AnotherModel = Backbone.Model.extend({
    initialize: function() {
    eventBus.on('ajax-called', this.ajaxCallingHandler);
    },  
});

附:另请注意,示例中的 ajaxForm successbeforeSubmit 处理程序是在 ajax 设置对象的范围内执行的。因此,您不能只在其中使用this.trigger(),而必须使用_.bind() 将这些函数绑定到window.UploaderView 或使用闭包。 More on scope binding.

【讨论】:

    【解决方案2】:

    AJAX 响应超出了视图的范围,因此“this”不属于视图。将响应移动到视图并应​​用 _.bindAll(this);解决您的问题。

    window.UploaderView = Backbone.View.extend({
        initialize: function() {
            _.bindAll(this);
            this.setElement(this.options.base_div);
            this.$el.find('form').ajaxForm({
                beforeSubmit: this.onBeforeSubmit,
                success: this.onSuccess,
                dataType: 'json,'
            });
        },
        onBeforeSubmit : function() {
            this.trigger('ajax-calling');
        },
        onSuccess: function(responseJSON) {
            this.trigger('ajax-called', responseJSON);
        }
    });
    
    var update_uploader = new window.UploaderView({
        base_div: $('#update-upload-action'),
    });
    
    var trigged = new window.UploaderView({
        initialize: function() {
            this.options.parent_view.on('ajax-calling', function() {
                alert('calling!');
            });
        },
    }); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      相关资源
      最近更新 更多