2015-06-24 2 views
10

Ich bin ziemlich neu in Backbone und habe mich gefragt, wie man auf Daten und Funktionen eines Modells von einer Ansicht aus zugreifen kann, die das Modell als Abhängigkeit einfügt.Backbone: Daten und Funktionen des Modells in der Ansicht verwenden

Mein Modell sieht wie folgt aus:

countries.coffee

define [ 
    'underscore' 
    'backbone' 
    'parse' 
], (_, Backbone, Parse) -> 
    'use strict'; 

    class CountriesModel extends Parse.Object 

    countries: ['GB','US','FR','JP','WL','ZM','NG'] 

    returnCode = (code) -> 
     return code 

Und meiner Meinung nach sieht wie folgt aus:

country.coffee

define [ 
    'jquery' 
    'underscore' 
    'backbone' 
    'templates' 
    'models/projects' 
    'models/countries' 
], ($, _, Backbone, JST, CountriesModel, ProjectModel) -> 
    class CountryView extends Backbone.View 

    ... 

    console.log countries 

    returnCode(4) 

I bin ich Injizieren des CountriesModel als Abhängigkeit, aber wenn ich die Funktion aufrufen oder die countries log ich die folgende Fehlermeldung erhalten:

Uncaught ReferenceError: returnCode is not defined 

ich nicht herausfinden können, was mache ich falsch. Jede Hilfe wird geschätzt. Danke im Voraus!

UPDATE

ich den Code oben aktualisiert haben ein bisschen mehr Kontext.

Ich versuche, ein wiederverwendbares Modell (CountriesModel) zu erstellen, so dass ich auf dieses countries Array und die returnCode Funktion auf verschiedenen Ansichten über meine App zugreifen kann. Aber ich kann nicht herausfinden, wie man auf sie auf meinem CountryView zugreift.

Mein CountryView wird benötigt schon ein Modell ProjectModel, und ich bin in der Lage aus ProjectModel wie diese Funktionen und Arrays zu nennen:

this.model.exampleArray
this.model.exampleFunction()

Ich kann nicht herausfinden, wie ich Funktionen oder Arrays von meinem CountriesModel aufrufen.

Wer weiß, was ich falsch mache?

+0

Nicht sicher, was Sie mit "injizieren" meinen, Sie benötigen in dem Modell und instanziieren es in der Ansicht? Das ist in Ordnung, und Sie könnten darauf zugreifen, was Sie wollen. Sie haben den wichtigen Teil des Codes nicht gezeigt, so dass ich nicht sehen kann, was Sie falsch gemacht haben. –

+0

@DominicTobias Entschuldigung, ich meinte, wie Sie sagten und instanziieren. Ich habe den Code aktualisiert, um ein wenig mehr Kontext zu bieten. – realph

+0

Ich denke, dass Sie die Reihenfolge Ihrer Abhängigkeiten im Beispiel ändern müssen, sollte sein: '($, _, Backbone, JST, ProjectModel, CountriesModel)'. –

Antwort

3

TBH Ich verstehe nicht wirklich, warum Sie Ihr Modell als Deps verwenden. Eine gute Ansicht sollte vom Modell abstrahieren und das Modell sollte an die Ansicht von der Route angehängt werden.

// this goes in your view file 
var CountryView = Backbone.view.extend({ 
    // here goes all the view logic to display the model data 
    // you can refer to your model using this.model 
}) 

... 
// in the router file 
var myModel = new CountriesModel(); 

var router = Backbone.router.extend({ 
    routes: { 
     "": home, 
     "home": home 
    }, 
    home: function(){ 
     var view = new CountryView({ model: myModel}); 
     view.render(); //if you didn't rendered the view in the initialize method 
    } 
}) 

Sie ein anderes Modell in der Ansicht zugreifen kann es zur Laufzeit im Router Befestigung

... 
// in the router file 
var myModel = new CountriesModel(); 
var anotherModel = new ProjectModel(); 


var router = Backbone.router.extend({ 
    routes: { 
     "": home, 
     "home": home 
    }, 
    home: function(){ 
     var view = new CountryView({ 
           model: myModel 
           anotherModel: anotherModel 
           }); 
     view.render(); //if you didn't rendered the view in the initialize method 
    } 
}) 

und in Country befestigen Sie es in der Initialisierungsfunktion

initialize: function (options){ 
    this = _.extend(options, this) 
    // or 
    // this.anotherModel = options.anotherModel 
    // this.model = options.model 
} 

Aber Sie sollten Sie nicht Modelle in einer Ansicht mischen, haben Sie einfach eine andere Ansicht für das projectModel und verwenden Sie sie beide bei Bedarf

// something like 
var countryView = new CountryView({model: myModel}); 
var projectView = new ProjectView({model: anotherModel}); 

und machen sie zusammen vom Router

+0

Ich verwende mein Modell als Abhängigkeit, weil ich Daten und Logik aus dem Modell in meine Sicht einbringen muss. Ich hatte den Eindruck, dass das der Weg war, es zu tun? – realph

+0

Sie sollten unbedingt diese zwei http://backbonejs.org/#View-rendering, http://backbonejs.org/#Model-View-separation und ein Tutorial aus dieser Liste https://github.com/jashkenas/ lesen Backbone/Wiki/Tutorials% 2C-Blog-Posts-und-Beispiel-Sites. Mein Tutorial der Wahl war irgendwo https://github.com/jashkenas/backbone/wiki/Tutorials%2C-blog-posts-and-example-sites#user-content-wine-cellar-app-by-christophe-coenraets Auf youtube gibt es ein Video davon. – EdoPut

3

Ihrer Ansicht Sie Modelle andere als die instanziieren kann, die bei this.model verwiesen wird. Z. B:

var SomeView = Backbone.View.extend({ 

    initialize: function() { 
     this.countriesModel = new CountriesModel(); 

     // Anywhere in your view do stuff with `this.countriesModel`. E.g: 
     // this.listenTo(this.countriesModel, ...) 
     // this.countriesModel.fetch() 
     // etc 
    } 

}); 
+0

Ich konnte das Array in der Ansicht mit 'this.countriesModel.countries' aufrufen, aber aus irgendeinem Grund funktioniert die Funktion nicht mit folgendem:' this.countriesModel.returnCode (4) '. Ich erhalte diesen Fehler: 'Uncaught TypeError: this.countriesModel.returnCode ist keine Funktion'. Irgendwelche Ideen? – realph

+0

@realph Ich bin nicht vertraut mit Kaffee-Skript, aber wenn Sie eine Funktion mit diesem Namen in Ihrem Modell hatte, würde es funktionieren, am besten ist, so schreiben 'Debugger;' über die Ausnahmezeile und in Chrome mit dem Inspektor geöffnet führen Sie es, Dann prüfe in der Konsole, was drin ist. 'this.countriesModel' –

+0

Seltsam. Ich kann auch nicht herausfinden, was der Debugger gerade macht. Ich kann ein Array erfolgreich zurückgeben, aber kein Objekt - es wird als "undefiniert" zurückgegeben. Ich kann auch keine Funktion zurückgeben, es sagt nur, dass es keine Funktion ist. So frustrierend. – realph

4

Ich denke, dass in diesem besonderen Fall wäre es sinnvoll sein, dass Sie ein Modell „countryModel“ zu schaffen und eine Rückgrat Sammlung „countriesCollection“. Aber das ist vielleicht nicht die Natur Ihrer Frage (Ihr Update zeigt an, dass Sie mit der Wiederverwendbarkeit des Modells zu kämpfen haben), deshalb werde ich das in meiner Antwort nicht berücksichtigen.
Ich weiß nicht, coffeescript, aber ich werde mit Javascript arbeiten.
Die Antwort ist in der Tat technisch Modelle über den options Parameter an die Ansicht während der Instanziierung übergeben.

Ich denke, dass es insgesamt eine gute Idee ist, Presenter-Objekte zu verwenden, um bestimmte Ansichtengruppen zu verwalten. Dieses Objekt würde Sichten instanziieren, die verwandt sind, und wie Sie es erwähnten, ermöglichen Sie, eine Instanz des countriesModel in diesen Präsentator zu injizieren.
Stellen Sie sich hypothetisch vor, dass Sie über eine Webanwendung verfügen, die eine Karte und eine Liste mit Orten darstellt, die aus irgendeinem Grund das von Ihnen beschriebene Modell erfordern. Sie könnten Code haben, der wie folgt aussieht:

var countriesModel = new CountriesModel(); 

var headerPresenter = new HeaderPresenter(); 
var mapPresenter = new MapPresenter(countriesModel); 
var listPresenter = new ListPresenter(countriesModel); 

Was passiert, ist, dass Sie das Modell nur einmal, instanziiert und die Instanz in die Moderatoren injizieren, die sie benötigen.
Im Presenter-Objekt können Sie sofort auf die Eigenschaften/Methoden zugreifen, die für das übergebene Modell festgelegt wurden.

Mit diesem Ansatz können Sie schnell feststellen, welche Präsentatoren das wiederverwendbare Modell benötigen.
Wenn Sie die Komponente auch in neuen Präsentatoren benötigen, können Sie sie problemlos weiterleiten.
Innerhalb des Präsentators können Sie dann noch auswählen, zu welchen Ansichten Sie das Modell senden möchten.

Eg. Liste Moderator:

function listPresenter(countriesModel){ 
    this.listView = new ListView({ "model": countriesModel); 
    //More views can be added with the same model instance 
}; 

Entweder aus den Ansichten oder die Moderatoren, Sie sind in der Lage, an Veranstaltungen auf dem Modell zu hören, seine Methoden ausführen und neu rendern die Ansichten.
Persönlich verwalte ich diese Logik vom Presenter, weil dies der Ort ist, an dem ich andere injizierte Dienste und Komponenten zb ausführen kann. Serveraufrufe oder spezifische Berechnungen, die für verschiedene Ansichten üblich sind. Die Handhabung dieser allgemeinen Logik für verschiedene Sichten kann leicht durch Übergeben eines Ereignisaggregators an jede der Sichten durchgeführt werden.Die Ansichten lösen benutzerdefinierte Ereignisse aus, um das Erforderliche auszuführen, und der Präsentator hört benutzerdefinierte Ereignisse ab, führt die erforderliche Logik aus und rendert Ansichten (neu).
Ich bevorzuge es, die Ansicht sauber und konzentriert auf DOM-Interaktion/DOM-Ereignisbindung zu halten.

Sidenote: Backbone Marionette bietet einen App-Level-Event-Aggregator, der Ihnen den Aufwand erspart, Event-Aggregatoren auf jede Ansicht einzeln zu übertragen.

var someView = new SomeView(); 
var region = new Marionette.Region({ el: "#some-region" }); 
region.show(someView); 

Re-Ansichten, durch Verwendung von Mario Regionen Speichersicher: durch die Verwendung Syntax wie
Es ist auch eine sehr bequeme lib Ansichten von den Vortragenden zu machen.

Hoffentlich hilft das.