简体   繁体   中英

Backbone.Marionette nested ItemView either not rendering or rendering “blank” view/template

On navigating to a specific URL, a controller method is fired, which loads an ItemView into one of my application's regions. This ItemView itself (the parent) will contain a handful of child ItemViews, rendering them all when it's rendered itself. Here's the parent ItemView:

return Backbone.Marionette.ItemView.extend({
    template: Handlebars.compile(template),
    ui: {
        textInput01: "#text-input-01"
    },
    events: {
        // no events yet
    },
    initialize: function() {
        // no init yet
    },
    onRender: function() {
        this.appRoutefinderTextinputItemView = new AppRoutefinderTextinputItemView({parentView: this});

        $(this.ui.textInput01).html(this.appRoutefinderTextinputItemView.render());
    }
});

And here's the current sole ItemView:

return Backbone.Marionette.ItemView.extend({
    template: Handlebars.compile(template),
    events: {
        // no events yet
    },
    initialize: function() {
        // no init yet
    },
    onRender: function() {
        // no onRender yet
    }
});

For some reason I cannot fathom, though both the initialize and onRender methods on the child are firing, and all necessary data seems to be present, the child is either not being rendered or is being rendered in a "blank" manner, resulting in an unchanged parent view.

As far as I understand, I shouldn't need to call render() on the child, as it's implied when instantiating/referencing an ItemView? Even when I drop the render() call, the same result is come to.

I've got to assume there's something about rendering ItemViews from within other ItemViews that I'm just missing, but scouring through the docs didn't seem to help.

A secondary question would be: am I instantiating the child views in the proper manner, or is there a better way to do so?

*EDIT - So after some experimenting, it appears that the "accepted" solution is simply to make the parent view a Layout, which is an extended ItemView. This does work. However, I'm still left wondering why an ItemView within an ItemView doesn't work. Am I intended to integrate a hand-written render() method on the ItemView, were I to keep it that way?

The problem with your original code is this line:

$(this.ui.textInput01).html(this.appRoutefinderTextinputItemView.render());

The render method of a backbone view does not returned the rendered HTML. This method does the rendering and updates the el of the view. The return value of this method is the view itself. Marionette does not change this behavior.

You need to change the code to populate the textInput01 with the view's el . Also note that the this.ui.textInput01 is already a jQuery selected object so you don't need to wrap that again.


this.appRoutefinderTextinputItemView.render();
this.ui.textInput01.html(this.appRoutefinderTextinputItemView.el);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM