Wie rufe ich ein einzelnes Modell in Backbone ab?


93

Ich habe ein ClockModell in Backbone:

var Clock = Backbone.Model.extend({});

Ich versuche, eine Instanz davon zu erhalten, die die neuesten Informationen enthält /clocks/123. Einige Dinge, die ich versucht habe:

eine "Klassen" -Methode

Clock.fetch(123)
// TypeError: Object function (){ ... } has no method 'fetch'

Erstellen einer Instanz und anschließendes Aufrufen fetch:

c = new Clock({id: 123})
c.fetch()
// Error: A 'url' property or function must be specified

eine Sammlung

Ich habe versucht, eine AllClocksSammlungsressource zu erstellen (obwohl ich für so etwas auf der Seite keine Verwendung habe):

var AllClocks = Backbone.Collection.extend({
  model: Clock,
  url: '/clocks/'
});
var allClocks = new AllClocks();
allClocks.fetch(123);
// returns everything from /clocks/

Wie bekomme ich nur eine API-gestützte Uhr?


IMHO gehört es zur Sammlung. So etwas wie Collection # fetchOne (ID, Rückruf).
Julian Maicher

Antworten:


26

Ihr zweiter Ansatz ist der Ansatz, den ich verwendet habe. Fügen Sie Ihrem Uhrenmodell Folgendes hinzu:

url : function() {
  var base = 'clocks';
  if (this.isNew()) return base;
  return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + this.id;
},

Bei diesem Ansatz wird davon ausgegangen, dass Sie Controller mit dem Hashbang in Ihrer URL wie http://www.mydomain.com/#clocks/123 implementiert haben. Er sollte jedoch auch dann funktionieren, wenn Sie dies noch nicht getan haben.


3
Es gibt eine Möglichkeit, dies zu vermeiden, wie in der Dokumentation zum Backbone-Modell documentcloud.github.com/backbone/#Model-url
makevoid

@makevoid your Ich konnte das Beispiel, das Sie im Kaffeeskript oder in der Dokumentation angegeben haben, nicht zum Laufen bringen. Das Beispiel von Andrew funktioniert. Könnten Sie ein Beispiel mit foo.url () bereitstellen. Es sagt mir immer, dass es keine Funktions-URL gibt.
Roberto Alarcon

@makevoid Es scheint, dass die Methode, auf die Sie sich beziehen, nur funktioniert, wenn das Modell in einer Sammlung erstellt wurde. Beachten Sie die Sammlung in [collection.url]/[id].
Steven Devijver

@makevoid können Sie bitte einen funktionierenden Link bereitstellen? Leider ist dieser
vorerst

Hier ist der Arbeitslink (sie haben das Dokument verschoben! Wow, 5 Jahre sind vergangen, meine Güte): backbonejs.org/#Model-url - @StevenDevijver ist korrekt
makevoid

137

Versuchen Sie, urlRoot im Modell anzugeben :

Aus den Dokumenten:

var Book = Backbone.Model.extend({urlRoot : '/books'});
var solaris = new Book({id: "1083-lem-solaris"});
solaris.fetch();

2
Das ist gut, aber manchmal möchten Sie das Modell nicht erneut aktivieren. Wenn Sie einen bestimmten Artikel für dasselbe Modell abrufen möchten, können Sie einen stillen Satz ausführen : currentBook.set('id', 13423, {silent:true}). Das funktioniert auch, aber ich bin mir nicht sicher warum:currentBook.id = 13423
SimplGy

1
@ SimplGy, das funktioniert, weil model.idim Wesentlichen gleichbedeutend ist mit model.attributes.id. Wenn Sie anrufen model.set('id'), setzt Backbone auf das model.id, was Sie angegeben haben. Und model.idwird beim Erstellen der modellspezifischen URL verwendet.
Lambart

26

Ich persönlich empfehle, die Dokumentation zur Model # url-Methode zu befolgen

model = new Model(id: 1)
view = new View(model: model) 
collection = new Collection([model])
model.fetch()

Denken Sie daran, in Ihrer Sammlung die Sammlungs-URL hinzuzufügen:

url: "/models"

und in der Initialisierungsfunktion Ihrer Ansicht tun Sie Folgendes:

this.model.bind("change", this.render)

Auf diese Weise führt das Backbone eine Ajax-Anfrage unter Verwendung dieser URL durch:

"/models/1"

Ihr Modell wird aktualisiert und die Ansicht gerendert, ohne dass Collection # url oder Model # urlRoot geändert werden

Hinweis: Entschuldigung, dieses Beispiel wurde im Kaffeeskript veröffentlicht, aber Sie können es leicht in js übersetzen, indem Sie var-Anweisungen hinzufügen


Anscheinend funktioniert das nicht. Rufen Sie nicht einmal den Server an, wenn Sie fetch im Modell (oder in der Sammlung) aufrufen
Ricardo Amores

Das sieht gut aus, aber die Sammellinie sieht in Fällen unangenehm aus, in denen wir die Sammlung nicht wirklich brauchen.
Dingle

Ich konnte das nicht zum Laufen bringen: this.model.get ('field'). Sieht aus wie das Modell erstellt wird
Unterobjekt

1
this.model.bind ("change", this.render, this) hat bei mir gut
funktioniert

1
@UlysseBN ja (war Jahr 2011), können Sie var-Anweisungen hinzufügen, {}innerhalb der ()'s für die übergebenen Objekte und optional ;am Ende der Zeilen
makevoid

12
var Person = Backbone.Model.extend({urlRoot : '/person/details'});
var myName = new Person({id: "12345"});
myName.fetch();

Als Ergebnis stellen Sie eine Ajax-Anfrage an die

URL http://[domainName]/person/details/id 

und Sie haben die JSON-Antwort zurück.

Enjoiiii !!!


2
Dies ist die gleiche Lösung wie @ Hernan
Brenden

0

... und tun Sie dies, wenn Sie den abschließenden Schrägstrich auf dem Modell urlRoot nicht möchten:

    url : function() {                        
        return this.urlRoot + this.id;
    },

0

Sie sollten wahrscheinlich über eine Sammlung auf das Objekt zugreifen und es die ganze Zeit in der Sammlung behalten. So geht's:

var AllClocks = Backbone.Collection.extend({
  model: Clock,
  url: '/clocks/'
});

var allClocks = new AllClocks();
my_clock = allClocks.add({id: 123});
my_clock.fetch()

2
Das weißt du nicht. Vielleicht braucht er nur eine Uhr. Angenommen, ich möchte einem Client ein einzelnes Modell eines Benutzerdatensatzes präsentieren. Sollte er auch Zugriff auf eine Sammlung aller Benutzer haben? Manchmal brauchen die Leute nur einen Rat, während sie versuchen, ihren Anwendungsfall privat zu halten. Antworte einfach.
Adrian Bartholomew

0

Ich möchte die RESTful-URL verwenden, konnte aber nicht verstehen, warum 'postId' nicht zur Basis-URL hinzugefügt werden kann.

var PostModel = Backbone.Model.extend({
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});

var post = new PostModel({
            postId: 1
        });
alert(post.url());

Dann weiß ich erst, nachdem ich 'idAttribute' als 'postId' in Model festgelegt habe, dass ich die richtige URL erhalten kann. so was:

var PostModel = Backbone.Model.extend({
    idAttribute: 'postId',
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.