使用 MarionetteJS 处理来自其他模块的 DOM 属性的最佳方法是什么?

What is the best way to deal with DOM attributes from other modules with MarionetteJS?

现在我经常使用 Backbone.Marionette,我担心什么是处理 DOM 外部属性的最佳方法。

有时候我需要做这样的事情:

我的-view.js

var MyView = ItemView.extend(
//...
//insert a lot of code here
//...
myFunction: function() {
    var someKindOfCalculation = this.$('.my-field').height() + Backbone.$('.my-external-module').height();
     //...
}

其中 .my-external-module 是另一个 MarionetteJS 模块内的 DOM 元素。 我目前解决这个问题的方法是这样的:

我的-view.js

//Some way to obtain the App.events variable(browserify, requireJS, global...)
//...
var MyView = ItemView.extend(
//...
//insert a lot of code here
//...
myFunction: function() {
    App.events.on('app:MyOtherModule:height:returned', function(heightForModule) {
        var someKindOfCalculation = this.$('.my-field').height() + heightForModule;
        //...
    });
    App.events.trigger('app:MyOtherModule:height');
}

我的-其他-module.js

//Some way to obtain the App.events variable(browserify, requireJS, global...)
//...
var MyOtherModule = Controller.extend({
    //...
    //insert a lot of code here
    //...
    start: function() {
        App.Events.on('app:MyOtherModule:height', function() {
            App.Events.trigger('app:MyOtherModule:height:returned', this.view.$el.height());
        });
    }    
})

虽然它工作正常,但这种获取 'external' DOM 属性的方式对我来说太奇怪了,因为每次你想获取外部属性时我们都包含一个新的回调。 当这些 DOM 元素不在我们当前的 module/view 范围内时,您是否使用另一种方法来获取 DOM 属性?这种获取数据的方式对你有效吗?

目前,Marionette 附带 Backone.Wreqr,但对于消费者而言,Wreqr 和 Radio 之间的区别只是语义上的。我将向您展示如何设置和使用两者的请求响应处理程序。

使用请求响应处理程序,您不必确保已创建 my-view.js,因为 my-view.js会主动请求数据,而不是等待my-other-module.js发布。

Backbone.Wreqr

使用您在 post 中共享的视图,您首先要在 my-other-module.js 中设置请求响应处理程序.我们将在 my-other-module.js 视图中设置请求响应处理程序,而不是在控制器中触发事件,我们称之为 我的其他-view.js.

设置处理程序

首先您必须启用请求消息系统,就像您使用 App.events 一样。因此,在您应用程序的某个集中部分(例如主控制器),您将执行:

App.reqres = new Backbone.Wreqr.RequestResponse();    

我的-其他-view.js

var MyOtherView = ItemView.extend({
  initialize: function () {
    this.setupHandlers();
  },

  setupHandlers: function() {
    App.reqres.setHandler('app:MyOtherModule:height', function(){
      return this.view.$el.height();
    });
  }
});

请求数据

而在 my-view.js 上,您只需传递 App 引用即可获取 App.reqres 并调用要求。像这样:

我的-view.js

var MyView = ItemView.extend{(
  //...
  //insert a lot of code here
  //...
  myFunction: function() {
    var heightForModule= App.reqres.request('app:MyOtherModule:height');
    var someKindOfCalculation = this.$('.my-field').height() + heightForModule;                 
  }
});

就是这样!这当然可以节省很多代码。

Backbone.Radio

Radio 是 Wreqr 的优化(和更小)版本,保留了其功能。要使用它,我们只需采用API 的语言,但用法本质上是相同的。

首先,我们在应用程序的中心位置设置请求消息传递总线,

_.extend(App.reqres, Backbone.Radio.请求);

然后我们只需更改方法名称

我的-其他-view.js

var MyOtherView = ItemView.extend({
  initialize: function () {
    this.setupHandlers();
  },

  setupHandlers: function() {
    App.reqres.reply('app:MyOtherModule:height', function(){
      return this.view.$el.height();
    });
  }
});

我的-view.js

var MyView = ItemView.extend{(
  //...
  //insert a lot of code here
  //...
  myFunction: function() {
    var heightForModule= App.reqres.request('app:MyOtherModule:height');
    var someKindOfCalculation = this.$('.my-field').height() + heightForModule;                 
  }
});

最后一句话

Wreqr 和 Radio 都使用频道。通过通道,您可以创建专用的消息传递总线,将消息分开。看这里:Backbone.Radio Channels.