2016-11-03 2 views
-2

Also ich bin wirklich neu bei backbone.js und ich versuche, das grundlegende Konzept zu verstehen, wenn es darum geht, Teile (Ansichten/Modelle/Routen) mit anderen Teilen interagieren.Wie übergebe ich Referenzen von Ansichten/Modellen an andere Ansichten/Modelle/Routen in backbone.js

Hier ist ein Beispiel. Ich habe ein "Bildschirm" -Modellobjekt, das von einer "singleScreen" -Ansicht auf die Seite gerendert wird. Ich habe auch ein Sidebar-Modell und eine Ansicht, die gerendert wird. Wenn ich auf einen Link in der Seitenleiste klicke, möchte ich, dass ein anderes Bildschirmmodell-Objekt gerendert wird und etwas HTML in einem separaten html-div (der Überschrift) entsprechend dem "name" -Attribut geändert wird, das ich meinem Bildschirmmodell gegeben habe.

Also erste Frage, sollte der gesamte Code für das erneute Rendern einer anderen Ansicht und Ändern der Überschrift HTML in der Datei routes.js getan werden? Es sieht so aus, als würde diese Datei ziemlich schnell ziemlich groß werden. Wenn ja, wie erhalte ich einen Verweis auf das Modellobjekt, das ich in der Datei routes.js rendern möchte, damit ich auf Dinge wie myModel.name (welches in der app.js-Datei instanziiert wird) zugreifen kann?

Behandle ich die Browserhistorie und das Rendering meiner Ansicht als separate Dinge und füge Code für 'Link geklickt, rendere' -Funktionalität in meine app.js-Datei ein (die Datei, in der ich alle meine Objekte instanziiere)? Wenn dies der Fall ist, wie weiß meine App, was zu rendern ist, wenn ein Benutzer versucht, direkt zu einer Ansicht zu gehen, indem er die URL eingibt, anstatt auf?

OR, und dies ist das wahrscheinlichste Szenario, soweit ich das beurteilen kann,

verwende ich die initialize Funktionen meiner Modelle/Ansichten, die ein Ereignis auslösen/listenTo für, wenn ein Link angeklickt wird (oder Backbone .history() wurde geändert?) und rendern rendern?

Ich habe mich mit allen drei Ansätzen herumgeschlagen, konnte aber nicht verstehen, wie man Referenzen von Objekten an andere Teile der App weitergibt, ohne diese Objekte zu globalen Variablen zu machen (was sich so falsch anfühlt). Für das letzte Szenario habe ich mich mit Ereignissen herumgesprochen, aber überall wo ich gelesen habe, muss man einen Verweis auf das Objekt, das es auch hört, einfügen, was den ganzen Zweck des Einrichtens eines Ereignisobjekts und des Zuhörens zunichte zu machen scheint für ein Ereignis, anstatt nur den Zustand einer Variablen dieses Objekts abzufragen ...

z.

this.listenTo(sidebarModel , "change:selected", this.render()); 

Wie gebe ich einen Verweis auf sidebarModel Objekt zu der Ansicht singleScreen für sie zu wissen, was es bedeutet, zu hören zu sein.

Ich bin nicht wirklich auf der Suche nach einer codierten Antwort, mehr nur ein Verständnis für Best Practices und wie Dinge zu tun sind. Ich fühle mich wie ich bin nahe, aber ich weiß, ich vermisse/nicht etwas zu verstehen deshalb bin ich nicht in der Lage, das selbst herauszufinden, daher würde ich ein bisschen aufschlussreich über das ganze Thema sein. Vielen Dank.

Antwort

1

Zuerst müssen Sie die Rolle der einzelnen Backbone-Klassen verstehen. Das Lesen auf MVC zuerst könnte helfen.

Modell

Das Modell ist nicht erforderlich, wenn eine Ansicht zu machen. Seine Aufgabe besteht darin, die Daten zu verarbeiten, die lokal oder von einer API stammen können. Alle Funktionen, die sich auf die Daten auswirken, sollten im Modell enthalten sein, und ein Modell sollte nicht mit in Zusammenhang stehen.

Es gibt immer eine Ausnahme, wo Sie ein Modell verwenden könnten, um Daten zu behandeln, die nur mit dem Rendering zusammenhängen, aber Sie werden wissen, wenn Sie einen solchen Fall finden.

Ein einfaches Beispiel ist ein Buch:

// The Book model class 
var Book = Backbone.Model.extend({ 
    idAttribute: 'code', 
    urlRoot: '/api/book' 
}); 

// a Book instance 
var solaris = new Book({ code: "1083-lem-solaris" }); 

von einer API Fetching nennen würde:

// GET http://example.com/api/book/1083-lem-solaris 
solaris.fetch(); // this is async 

Beim Abrufen, die API die JSON codierten Daten zurückgibt.

{ 
    "code": "1083-lem-solaris", 
    "title": "Test title", 
} 

Die Attribute werden mit den vorhandenen Attributen verschmolzen, diejenigen hinzufügen, die noch nicht da sind, und die Werte von den bereits dort überschrieben werden.

Sammlung

eine Rolle Sammlung ist ein Array von Modellen zu verwalten, die wiederum aus einer API lokalen oder abgeholt werden. Es sollte nur Funktionen zum Verwalten der Sammlung enthalten.

var Library = Backbone.Collection.extend({ 
    model: Book, 
    url: '/api/book' 
}); 

var myLibrary = new Library(); 

// just adds an existing book to our array 
myLibrary.add(solaris); 

Sie eine Sammlung holen kann eine Reihe von vorhandenen Büchern aus einer API zu erhalten:

[ 
    { "code": "blah-code-123", "title": "Test title" }, 
    { "code": "other-code-321", "title": "Other book title" } 
] 

Mit der Sammlung ein neues Buch zu erstellen:

myLibrary.fetch(); 

Die API zurückgeben sollen und mit der API synchronisieren:

var myNewBook = myLibrary.create({ title: "my new book" }); 

Dies wird eine POST-Anfrage mit den Attributen senden und die API sollte zurückgeben:

{ "code": "new-code-123", "title": "my new book" }, 

Ansicht

Die Ansicht Griffe seine Wurzel DOM-Element. Es sollte Ereignisse aus seinem DOM verarbeiten. Es wird am besten verwendet, um kleine Komponenten zu verpacken und größere Komponenten aus kleineren Komponenten zu bauen.

Setzen Sie Links direkt in die Vorlagen, in die href eines Anker-Tags. Es ist nicht notwendig, Ereignisse dafür zu verwenden.

<a href="#my-route">link</a>` 

Hier ist, wie ich eine Liste (vereinfacht) rendern.

// book list item 
var BookView = Backbone.View.extend({ 
    tagName: 'li', 
    template: _.template('<a href="#book/<%= code %>"><%= title %></a>'), 
    initialize: function() { 
     // when the model is removed from the collection, remove the view. 
     this.listenTo(this.model, 'remove', this.remove); 
    }, 
    render: function() { 
     this.$el.empty().append(this.template(this.model.toJSON())); 
     return this; 
    } 
}); 

// book list 
var LibraryView = Backbone.View.extend({ 
    template: '<button type="button" class="lib-button">button</button><ul class="list"></ul>', 
    events: { 
     'click .lib-button': 'onLibButtonClick' 
    }, 

    initialize: function(options) { 

     this.listenTo(this.collection, 'add', this.renderBook); 
    }, 

    render: function() { 
     // this is a little more optimised than 'html()' 
     this.$el.empty().append(this.template); 

     // caching the list ul jQuery object 
     this.$list = this.$('.list'); 

     this.collection.each(this.renderBook, this); 

     return this; // Chaining view calls, good convention http://backbonejs.org/#View-render 
    }, 

    addItem: function(model) { 
     // Passing the model to the Book view 
     var view = new BookView({ 
      model: model 
     }); 
     this.$list.append(view.render().el); 
    }, 

    onLibButtonClick: function() { 
     // whatever 
    } 

}); 

Router

Die Router Griff Routen und soll so einfach wie möglich sein, um es zu vermeiden, dass zu schnell zu groß zu bekommen. Es kann Sammlungen und Modelle abrufen, oder die Ansicht kann damit umgehen, es ist eine Frage des Musters an diesem Punkt.

var LibraryRouter = Backbone.Router.extend({ 
    routes: { 
     '*index': 'index', 
     'book/:code': 'bookRoute', 
    }, 

    index: function() { 
     var library = new LibraryView({ 
      el: 'body', 
      // hard-coded collection as a simple example 
      collection: new Library([ 
       { "code": "blah-code-123", "title": "Test title" }, 
       { "code": "other-code-321", "title": "Other book title" } 
      ]) 
     }); 
     library.render(); 
    }, 
    bookRoute: function(code) { 
     var model = new Book({ code: code }); 
     // here, I assume an API is available and I fetch the data 
     model.fetch({ 
      success: function() { 
       var view = new BookPageView({ 
        el: 'body', 
        model: model 
       }); 
       view.render(); 
      } 
     }); 
    } 
}); 

Event

Alles in Backbone hat den Events mixin, auch das globale Objekt Backbone. So kann jede Klasse listenTo verwenden, um Callbacks an Ereignisse zu binden.


Es wäre sehr lange dauern, in der Tiefe in Backbone für alles zu gehen, also Fragen stellen und ich werde versuchen, meine Antwort zu verlängern.

+0

Super, danke für die Erklärung. Ok, ich denke, was ich ausgehängt habe, ist die Tatsache, dass ich versuche, eine Instanz eines Objekts zu erstellen und es weiterzugeben, während es so aussieht, als ob Sie neue Instanzen erstellen und die als Parameter benötigten Werte übergeben würden . (und ich nehme an, bereinigen Sie die alte Instanz, wenn Sie nicht mehr benötigen.) Beispiel, wo Sie erstellen 'var model = new Buch ({code: code});' – MattyB

+0

Um zu erklären, warum ich es aufgelegt habe weiter, mit der App, die ich zu versuchen und zu schaffen, Sie könnten es sich vorstellen, als wissend, dass Ihre Bibliothek immer nur 4 Bücher haben wird, und dass Sie alle Attributwerte für sie bereits kennen. Also habe ich versucht, diese 4 Bücher in meiner app.js gleich zu Beginn zu erstellen und dann Referenzen herumzugeben. Aber ich beginne zu verstehen, dass es am besten ist, eine neue Instanz eines Buchmodells mit den relevanten Daten zu erstellen. Das bedeutet, dass es nicht möglich ist, das DOM in etwas wie routes.js basierend auf Daten in meinem Buchmodell zu manipulieren. – MattyB

+0

Ok, dann Frage, Wenn meine Ansicht Vorlage für BookPageView hatte einen Aufruf, um den Namen des Modells '<%= name %>', in Ihrem Beispiel, wie würde view.render(); in Ihren Routen haben Zugang zu diesen Informationen? Da das einzige, was Sie übergeben haben, ist der 'code' beim Erstellen einer neuen Instanz des zu rendernden Buchs. – MattyB

Verwandte Themen