Backbone-View-Verschachtelung
Bin ich im Kreis herum, scheinbar etwas fehlt in meiner aktuellen app-Umsetzung backbone.js. Das problem ist ich habe einen master AppView, die initialisiert verschiedene Untersichten (einem graph, einer Tabelle von Informationen, etc) für die Seite. Mein Wunsch ist es, in der Lage sein, ändern Sie das layout der Seite abhängig von einem parameter flag übergeben entlang, während mit der Navigation.
Was ich laufen in einem Fall, wo der Untersichten, die Referenz zum dom-Elemente, wäre nach der Vorlage wiedergegeben wird, haben keinen Zugriff auf diese Elemente während der Haupt-AppView Initialisierung. Also die wichtigste Frage ist, wie kann ich sicherstellen, dass die richtigen dom-Elemente sind in jedem Fall binden Prozess um die Einrichtung zu erhalten, richtig?
Mit dem folgenden code, wenn ich ein Ereignis gebunden, um ein Modell zu ändern, die in meiner LayoutView, das layout gerendert wird, aber die nachfolgenden äußerungen nicht richtig wiedergegeben. Einige Sache habe ich bedacht wurde, um alle Ansichten '.el' Werte zu einem statischen element innerhalb der html-Struktur. Diese bekommt rendering auftreten, obwohl das scheint zu brechen Weg von der schönen scoping-Fähigkeit bereitgestellt durch die Verwendung von '.el'.
Beispielcode:
//Wrapped in jquery.ready() function...
//View Code
GraphView = Backbone.View.extend({ //init, model bind, template, supporting functions});
TableView = Backbone.View.extend({ //init, model bind, template, supporting functions});
LayoutView = Backbone.view.extend({
initialize: function() {
this.model.bind('change:version', this.render, this);
},
templateA = _.template($('#main-template').html()),
templateB = _.template($('#secondary-template').html()),
render: function() {
if ('main' == this.model.get('version')) {
this.el.html(this.templateA());
} else {
this.el.html(this.templateB());
}
},
});
MainView = Backbone.View.extend({
initialize: function() {
this.layoutView = new LayoutView({
el: $('#layoutContainer'),
model: layout,
});
this.graphView = new GraphView({
el: $('.graphContainer'),
model: graph
});
this.tableView = new TableView({
el: $('#dataTableContainer',
model: dataSet
});
},
});
//Model Code
Layout = Backbone.Model.extend({
defaults: {
version: 'main',
},
});
Graph = Backbone.Model.extend({});
dataSet = Backbone.Model.extend({});
//Router code...
//Fire off the app
AppView = new MainView($('#appContainer'));
//Create route, start up backbone history
HTML:
Für Einfachheit habe ich nur neu angeordnet, die divs zwischen den beiden layouts.
<html>
<head>
<!-- include above js and backbone dependancies -->
</head>
<body>
<script type="text/template" id="main-template">
<div class="graphContainer"></div>
<div class="dataTableContainer"></div>
<div>Some other stuff to identify that it's the main template</div>
</script>
<script type="text/template" id="secondary-template">
<div class="dataTableContainer"></div>
<div>Rock on layout version two!</div>
<div class="graphContainer"></div>
</script>
<div id="appContainer">
<div id="nav">
<a href="#layout/main">See Layout One</a>
<a href="#layout/secondary">See Layout Two</a>
</div>
<div id="layoutContainer"></div>
</div>
</body>
</html>
Schätzen, Einsicht/Eingabe, dass jeder von Euch haben kann. Danke!
- Nur zur info, du hast ein paar Tippfehler in deinem code ist es sicher davon ausgehen, dass diese copy/paste Probleme, nicht die eigentliche syntax-Fehler?
- Schuld kopieren/einfügen, wird die zugrunde liegende Logik, hoffentlich wird noch übermittelt. Vielen Dank für den Hinweis.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie eine Menge code fehlt in deinem Beispiel, aber wenn ich das richtig verstanden, das Problem ist, dass Sie versuchen, zu Rendern Ansichten, die davon abhängen, erzeugte HTML-von
LayoutView
, aber das layout gewählt wird asynchron, wenn das Modell aktualisiert wird, soLayoutView
noch nicht gerendert wurde noch.Gibt es (wie bei so ziemlich alles Backbone-bezogen) mehrere Ansätze, aber im Allgemeinen:
Wenn ich Ansichten, die davon abhängen, eine "Eltern" - Ansicht gerendert wird, werde ich die Verantwortung für die Instanziierung und Darstellung der diese Ansicht in der übergeordneten Ansicht - in diesem Fall
LayoutView
, nichtMainView
.Wenn die Eltern gerendert wird asynchron, die es braucht, um durchzuführen, die Instanziierung in der callback - hier die
LayoutView.render()
Methode.So, ich könnte die Struktur der code wie folgt:
Beachten Sie, dass Sie nicht passieren in einem
el
bei der Instanziierung - man könnte instanziieren Untersichten ininitialize()
, und legen Sie dieel
Eigenschaft insubview.render()
. Man könnte sogar instanziieren inMainView.initialize()
, wie Sie jetzt tun, und übergeben Sie die Aussicht aufLayoutView
zu erbringen asynchron. Aber ich denke, dass der obige Ansatz ist wahrscheinlich sauberer.