I have created a simple view, MyView
, that extends from ItemView
. Then when I create the instance of MyView
, I am trying to add references to UI elements within the view as well as events that use those UI elements.
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();
I am receiving the following error in the console:
Uncaught TypeError: Cannot read property 'changeModelNameButton' of undefined
I noticed that if I move the ui declarations to the view definition, it works fine, but I would like to know why I can't add those when I create the instance. Is there no way to add them to the instance or am I missing something?
Note: I am using Backbone 1.3.3, Marionette 2.4.4, Underscore 1.8.3, and jQuery 3.1.1
Not all the options are automatically overriding the view class properties when passed on instantiation.
ui
looks like it's not one of them.
Backbone will automatically apply the following (private) viewOptions
on a view:
// List of view options to be set as properties.
var viewOptions = [
'model',
'collection',
'el',
'id',
'attributes',
'className',
'tagName',
'events'
];
In the view constructor, this
is extended with the chosen options (source):
_.extend(this, _.pick(options, viewOptions));
ui
option?You either need to put the ui
hash in the view class definition, or to apply the ui hash yourself.
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);
}
});
Note that options passed to a view are available in this.options
automatically.
If you're going to mess around the ui
and the events
with its callbacks, it would be best to define a new view.
It looks like a XY problem where the real problem lies in the architecture of the app, but we can't help since you're asking about what's blocking you right now.