javascript alternative - backbone.js strukturiert verschachtelte Ansichten und Modelle





example tutorial (5)


Sie können zum Beispiel einige Erweiterungen, Backbone-Forms https://github.com/powmedia/backbone-forms . Um Ihrem Anwendungsfall zu folgen, definieren Sie ein Schema wie:

var ModelB = Backbone.Model.extend({
    schema: {
        attributeB1: 'Text',
        attributeB2: 'Text'
    }
});

var ModelC = Backbone.Model.extend({
    schema: {
        attributeC: 'Text',
    }
});

var ModelA = Backbone.Model.extend({
    schema: {
        attributeA1: 'Text',
        attributeA2: 'Text',
        refToModelB: { type: 'NestedModel', model: ModelB, template: 'templateB' },
        refToModelC: { type: 'NestedModel', model: ModelC, template: 'templateC' }
    }
});

Sehen Sie sich https://github.com/powmedia/backbone-forms#customising-templates für Teilvorlagen an.

Wichtige Teile sind hier type: 'NestedModel' und template: 'templateXXX' .

Dieses Plugin hat einige Einschränkungen, aber Sie können sich andere unter https://github.com/documentcloud/backbone/wiki/Extensions%2C-Plugins%2C-Resources ansehen.

Verwenden von backbone.js:

Ich habe eine Top-Level-ModelA, die 2 Attribute und 2 verschachtelte Modelle enthält, ModelB und ModelC. ModelB und ModelC haben jeweils zwei Attribute:

ModelA
    attributeA1
    attributeA2
    ModelB
        attributeB1
        attributeB2
    ModelC
        attributeC1
        attributeC2

Es gibt ein ViewA für ModelA und ein ViewB für ModelB. Die Renderfunktion von ViewA platziert ein neues div auf den Körper, während das Rendering von ViewB ein h1 erstellt. ViewAs Initialisierung ruft ViewBs Render auf, um h1 in das neue div einzufügen. Der Grund für diese Trennung ist, dass sich das h1 ändern kann und unabhängig von ViewA erneut gerendert werden muss.

ViewA
    initialise: 
        //call ViewA's own render function
        this.render() 

        //call ViewB's render function that further modifies the $("#new") div created earlier.
        $("#new").append(ViewB.render().el)

    //ViewA's own render function
    render: //place <div id="new"></div> onto 'body'

ViewB
    render: //create a <h1></h1>
    funcB1: //can this access it's parent ModelA's attributes and other objects?

Q1: ViewB hat eine Funktion funcB1. Kann diese Funktion auf die Attribute des übergeordneten Modells zugreifen? Attribute wie AttributA1 oder sogar AttributC1 (was wäre ein Geschwister / Cousin)?

F2: Kann funcB1 als weitere Erweiterung von Q1 auf die mit ViewA verbundenen DOM-Elemente zugreifen? (In diesem Beispiel ist das #new div?)

F3: Wie definiere ich im Allgemeinen die Assoziationen zwischen den Ansichten und den Modellen, wie oben beschrieben, damit alles gut zusammenpasst?

Ich weiß, dass diese Frage etwas abstrakt ist, aber alle schätzen jede Hilfe oder Richtlinien schätzen.




Es gibt das Backbone-Plugin Backbone-relational.js, das Eins-zu-Eins, Eins-zu-Viele- und Viele-zu-Eins-Beziehungen zwischen Modellen für Backbone bietet.

Ich denke, dass dieses js Ihre Bedürfnisse erfüllen wird. Vist BackboneRelational für mehr Dokumentation.




Um Attribute in verwandten Modellen erreichen zu können, muss das Modell ein gewisses Wissen darüber haben, mit welchen Modellen es verknüpft ist. Backbone.js behandelt nicht implizit Beziehungen oder Verschachtelung, was bedeutet, dass Sie selbst sicherstellen müssen, dass die Modelle voneinander wissen. Um Ihre Fragen zu beantworten, müssen Sie sicherstellen, dass jedes Kindmodell ein Attribut "Eltern" hat. Auf diese Weise können Sie die Verschachtelung zuerst bis zum Elternteil und dann bis zu allen Ihnen bekannten Geschwistern durchlaufen.

Um genauer mit Ihren Fragen zu sein. Wenn Sie ModelA initialisieren, erstellen Sie wahrscheinlich ModelB und ModelC. Ich würde daher vorschlagen, eine Verknüpfung zum übergeordneten Modell zu erstellen, indem Sie Folgendes tun:

ModelA = Backbone.Model.extend({

    initialize: function(){
        this.modelB = new modelB();
        this.modelB.parent = this;
        this.modelC = new modelC();
        this.modelC.parent = this;
    }
}

Auf diese Weise können Sie das Elternmodell in jeder untergeordneten Modellfunktion aufrufen, indem Sie this.parent aufrufen.

In Bezug auf Ihre Ansichten ist es für geschachtelte Backbone-Ansichten einfacher, jede Ansicht ein HTML-Tag darstellen zu lassen, indem Sie die Option tagName der Ansicht verwenden. Ich würde deine Ansichten folgendermaßen formulieren:

ViewA = Backbone.View.extend({

    tagName: "div",
    id: "new",

    initialize: function(){
       this.viewB = new ViewB();
       this.viewB.parentView = this;
       $(this.el).append(this.viewB.el);
    }
});

ViewB = Backbone.View.extend({

    tagName: "h1",

    render: function(){
        $(this.el).html("Header text"); // or use this.options.headerText or equivalent
    },

    funcB1: function(){
        this.model.parent.doSomethingOnParent();
        this.model.parent.modelC.doSomethingOnSibling();
        $(this.parentView.el).shakeViolently();
    }

});

Dann würde ich in Ihrem Anwendungsinitialisierungscode (z. B. in Ihrem Controller) ViewA initiieren und sein Element in das body-Element einfügen.




Die obige Lösung ist auf dem richtigen Weg, hat aber einige Probleme.

initialize: function(){
  this.viewB = new ViewB();
  this.viewB.parentView = this;
  $(this.el).append(this.viewB.el);    
}

Hauptsächlich gibt das toJSON () des Modells jetzt veraltete Daten zurück. Ich habe eine Lösung gepostet, um dieses Problem in einem backbone.js-Plugin zu beheben. Sie können es gerne verwenden.




Ich bin gerade mit diesem Loader gelungen:

https://github.com/aitoroses/vulcanize-loader

Unerhörte Sache ist, dass ich die Webkomponente installieren musste, die ich durch Bower wollte (Garn macht den Job auch). Danach referenzieren Sie sie manuell in der manuell erstellten Datei imperser.html und verweisen Sie dann am Ende auf diese Datei importer.html in Ihrem js-Modul:

import 'vulcanize!./importer.html';




javascript backbone.js