2012-05-18 9 views
7

Ist es möglich, eine Vorlage in einer Vorlage geschachtelt zu haben und über Backbone-Ansicht zuzugreifen?Backbone-Vorlage in einer anderen Vorlage geschachtelt

Zum Beispiel habe ich View1 mit Template1 und View2 mit Template2. Template2 muss sich tatsächlich in einem DIV innerhalb von Template1 befinden. Ich lege den DIV-Container für template2 in template1 mit der entsprechenden ID ab, aber es wird nicht angezeigt, wenn die Seite gerendert wird. Wenn ich den Template2-div-Container aus Template1 entferne und ihn einfach in den Seitenkörper lege, funktioniert er einwandfrei.

Also frage ich mich, ob das möglich ist, oder ob ich die Ansichten/Modelle usw. verschachteln muss, damit das funktioniert?

Die Daten in Template2 haben keine technische Beziehung zu Template1 muss nur an einer Position auf der Seite angezeigt werden, die in Template1 eingebettet ist.

+0

Können Sie etwas Code teilen? –

+0

Ich weiß, dass dies Ihre Frage nicht beantwortet, aber Ember js unterstützt etwas, das nah dran ist. Sie können verschachtelte Ressourcen definieren. Mit sorta können Sie Vorlagen in Vorlagen verschachteln. http://emberjs.com/guides/routing/defining-your-routes/ –

Antwort

20

Die Art, wie ich in der Vergangenheit damit umgegangen bin, besteht darin, beide Ansichten separat zu definieren und dann beim Rendern von View1 ein neues View2 zu erstellen, es zu rendern und in View1 einzufügen. Also:

window.View1 = Backbone.View.extend({ 
    render: function() { 
     this.view2 = new View2(); 
     this.$('insert-view-here').append(this.view2.render().el); 
    } 
}); 
+0

Dies funktionierte, danke. – mbr1022

+1

Wie gehen Sie in diesem Fall mit der Veränderung des inneren Elements um? Rendern Sie immer von oben nach unten, kann sich das innere Element irgendwie verändern? –

+0

Änderungen an den inneren Elementen können von der 2. Ansicht behandelt werden, so wie Sie sie in jeder anderen Situation behandeln würden.Wenn aus irgendeinem Grund die übergeordnete Ansicht oder das Modell geändert wird und HTML erneut gerendert werden muss, werden die untergeordneten Ansichten innerhalb dieser Rendermethode neu erstellt. – RTigger

0

Die typische Art und Weise, wie ich es verstehe von Ansichten als komplette Objekte zu denken, dass Sie in jedem anderen einbetten können. Nehmen wir an, Sie haben zwei Ansichten, ViewA und ViewB. Der folgende Code zeigt, wie Sie ViewB in ViewA anfügen können.

# this is coffeescript, but it's easily translated to JS 
class ViewA extends Backbone.View 
    initialize:() -> 
     this.render() 

    render:()-> 
     this.$el.append(new ViewB().$el) 
     this.$el.append(new ViewB().$el) 
     return this 

Sie Lust bekommen konnte, mit wie ViewB verwaltet wird (es Eigenschaften zuweisen oder was auch immer) oder verschiedene Konstruktorargumente in jede ViewB Instanz übergeben.

4

Sie sollten Unteransichten dafür erstellen.

Ich mag Subviews in Schließung zu privatisieren und die öffentliche Sicht zurückzugeben.

var View = (function (BV) { 
    var View, Subview; 

    // Only this main view knows of this subview 
    Subview = BV.extend({ 
     template: _.template(subtmpl), 

     render: function() { 
      this.$el.html(this.template(this.model.toJSON())); 
      return this; 
     } 
    }); 

    View = BV.extend({ 
     template: _.template(tmpl), 

     render: function() { 
      this.$el.html(this.template(this.model.toJSON())); 

      var subview = new SubView({ model: this.model }); 

      // replace a div in your template meant for teh subview with the real subview 
      this.$el.find("#subview").replaceWith(subview.render().el); 

      return this; 
     } 
    }); 

    return View; 

}(Backbone.View)); 

var view = new View({ model: user }); 
var subview = new Subview; // Reference Error 
2

Eine weitere Option, die nützlich ist, wenn Sie Template2 mehrere Male innerhalb Template1, sagen als <li> Elemente innerhalb eines <ul> müssen, einen Template2 Funktion in Template1 passieren soll. (Von Rico Sta Cruz' Backbone Patterns.)

TasksList = Backbone.View.extend({ 
    // Template1, inlined in js. 
    template: _.template([ 
    "<ul class='task_list'>", 
     "<% items.each(function(item) { %>", 
     "<%= itemTemplate(item) %>", 
     "<% }); %>", 
    "</ul>" 
    ].join('')), 

    // Template2, inlined in js. 
    itemTemplate: _.template(
    "<li><%= name %></li>" 
), 

    render: function() { 
    var html = this.template({ 
     items: tasks /* a collection */, 
     itemTemplate: this.itemTemplate 
    }); 

    $(this.el).append(html); 
    } 
}); 
0

Eine mageren Lösung, ohne die Notwendigkeit für jQuery append() oder das zusätzliche SubView Objekt eines doppelten jQuery Rahmen betreffen, vorrendern/precompile streng an die Unterstreichungsverfahren verwendet wird, und legen Sie die subview Als String verwenden Sie innere Kommentartags in Ihrer Hauptvorlage.

View = Backbone.View.extend({ 
    template: _.template(...), 
    prerender: function(tpl,model){// pre-render a component 
     var template = _.template(tpl); 
     return template(model); 
    }, 
    render: function(){ 
    var model = { ... }; 
    var component = this.prerender(this.itemTemplate, model); 
    this.$el.html(this.template(model).replace('<!--#component-->', component)); 
    } 
}); 

Es ist nützlich, vor allem, wenn die Vorlage nicht eine Konstante ist, und hängt von einer Eigenschaft des aktuellen Bereichs.

Beachten Sie, dass Sie für das Ausmaß dieser Frage das View2-Modell an die Komponente übergeben müssen.