使用Backbone.Marionette,为什么在创建视图的新实例时不能引用@ui 元素?

Using Backbone.Marionette, why can I not reference @ui elements when creating a new instance of a view?

我创建了一个从 ItemView 扩展而来的简单视图 MyView。然后,当我创建 MyView 的实例时,我试图在视图中添加对 UI 元素的引用以及使用这些 UI 元素的事件。

HTML

<div id="container"></div>

<script type="text/template" id="my-template">
    <p>This is a rendered template.</p>
  <button data-ui="changeModelNameButton">Change Model Name</button>
</script>

JS

// Define a custom view that extends off of ItemView
var MyView = Marionette.ItemView.extend({
  template: "#my-template"
});

// Instantiate the custom view we defined above
var view = new MyView({
  el: "#container",

  ui: {
    changeModelNameButton: '[data-ui~=changeModelNameButton]'
  },

  events: {
    'click @ui.changeModelNameButton': function() {
      alert('here'); 
    }
  }
});

// Render the view in the element defined within the custom view instantiation method
view.render();

我在控制台中收到以下错误:

Uncaught TypeError: Cannot read property 'changeModelNameButton' of undefined


我注意到如果我将 ui 声明移动到视图定义中,它工作正常,但我想知道为什么我在创建实例时不能添加这些声明。没有办法将它们添加到实例中,还是我遗漏了什么?

注意:我使用的是 Backbone 1.3.3、Marionette 2.4.4、Underscore 1.8.3 和 jQuery 3.1.1

覆盖视图属性的选项

并非所有选项在实例化时都会自动覆盖视图 class 属性。

ui好像不是其中之一

Backbone 将自动在视图上应用以下(私有)viewOptions

// List of view options to be set as properties.
var viewOptions = [
    'model', 
    'collection', 
    'el', 
    'id', 
    'attributes', 
    'className', 
    'tagName', 
    'events'
];

在视图构造函数中,this 使用所选选项 (source) 进行扩展:

_.extend(this, _.pick(options, viewOptions));

如何传递ui选项?

您需要将 ui 散列放在视图 class 定义中,或者您自己应用 ui 散列。

var MyView = Marionette.ItemView.extend({
    template: "#my-template",
    initialize: function(options) {

        // merge the received options with the default `ui` of this view.
        this.ui = _.extend({}, this.ui, this.options.ui);
    }
});

请注意,传递给视图的选项是 available in this.options automatically


这背后的真正目的是什么?

如果您要将 uievents 及其回调搞得一团糟,最好定义一个新视图。

看起来 XY problem 真正的问题在于应用程序的架构,但我们无能为力,因为您问的是现在是什么阻碍了您。