共享Marionette vent.on跨越不同的视图

时间:2014-02-20 13:49:51

标签: javascript backbone.js marionette

您好我有一个布局视图,其中包含许多过滤器部分和一个集合。过滤器部分在我的项目中共享,因此它们都会在触发时引用“filter:change”。

然而,我发现当我更改页面并导致“过滤器:更改”时,我会遇到上一个视图发布绑定被调用的问题(然后模板将从dom中删除)。

基本上,当我的布局视图关闭时,我需要取消绑定事件“filter:change”,以便下一个layoutview可以专门访问该触发器。

当前代码:

define([
  "text!app/templates/users/index.html",
  'app/views/users/collection',
  'app/views/users/partials/internal',
  'app/views/users/partials/enabled',
  'app/views/partials/location_id'
],
  function(Template, CollectionView, FilterInternalView, FilterEnabledView, FilterLocationIdView) {
    "use strict"

    return Backbone.Marionette.Layout.extend({


      template: Template,


      regions: {
        filterInternal: '#filterInternalContainer',
        filterEnabled: '#filterEnabledContainer',
        filterLocationId: '#filterLocationIdContainer',

        collectionLatch: '#collectionLatch'
      },


      initialize: function() {

        // horrible scope issues with javascript
        var that = this;

        // if the filter change event is triggered in a sub view
        MyApp.vent.on('filter:change', function() {
          // fetch the collection and pass its filters through
          that.renderCollection(that.getFilter());
        })
      },


      getFilter: function() {

        // create our new filter object using jQuery picking the values
        var filter = {
          from: "0",
          to: parseInt(100),
          enabled: $('#filterEnabled').val(),
          internal: $('#filterInternal').val(),
          location_id: $('#filterLocationId').val()
        };

        // passing it through a null stripper
        filter = _.cleanNullFieldsFromObject(filter);

        // set the filter object to local storage (extended, not typical)
        localStorage.setObject('userFilter', filter);

        return filter;
      },


      renderFilterEnabled: function(options) {
        this.filterEnabled.show(new FilterEnabledView(options));
      },


      renderFilterInternal: function(options) {
        this.filterInternal.show(new FilterInternalView(options));
      },


      renderFilterLocationId: function(options) {
        this.filterLocationId.show(new FilterLocationIdView(options));
      },


      renderCollection: function(options) {
        // render the post list
        this.collectionLatch.show(new CollectionView(options));
      },


      onRender: function () {

        // do we need to over write the filter object from local storage?
        var userFilter = localStorage.getObject('userFilter');

        // if local storage isn't empty then over ride the filter with it
        if (!_.isEmpty(userFilter)) {
          this.filter = userFilter;
        } else {
          this.filter = this.getFilter();
        }

        // render the filters on our page
        this.renderFilterEnabled(this.filter);
        this.renderFilterInternal(this.filter);
        this.renderFilterLocationId(this.filter);

        // render the collection
        this.renderCollection(this.filter);
      },


      onClose: function() {}


    })
  })

//部分视图

define(["marionette", "text!app/templates/partials/location_id.html", 'app/models/location'],
  function(Marionette, Template, Model) {
    "use strict"
    return Backbone.Marionette.ItemView.extend({
      template: Template,


      events: {
        'change #filterLocationId': 'onFilter'
      },


      initialize: function(options) {
        this.value = _.isEmpty(options) ? '-' : options.location_id;
      },


      onFilter: function() {
        MyApp.vent.trigger('filter:change');
      },


      serializeData: function() {
        return {values: new Model().getIds(), value: this.value};
      }


    })
  })

我查看了文档:https://backbonemarionette.readthedocs.org/en/latest/marionette.eventbinder.html#unbind-a-single-event

并尝试:

  onClose: function() {
    MyApp.vent.off('filter:change');
  }

但无论如何,即使下一个视图重新开启,该事件也不起作用。

1 个答案:

答案 0 :(得分:1)

尝试更改:

MyApp.vent.on('filter:change', function() {
    // fetch the collection and pass its filters through
    that.renderCollection(that.getFilter());
})

通过

this.listenTo(MyApp.vent, 'filter:change', function() {
    // fetch the collection and pass its filters through
    that.renderCollection(that.getFilter());
})