Comment récupérer un seul modèle dans Backbone?

93

J'ai un Clockmodèle dans Backbone:

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

J'essaie d'obtenir un exemple de cela qui contient les dernières informations /clocks/123. Certaines choses que j'ai essayées:

une méthode de niveau "classe"

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

créer une instance puis l'appeler fetch:

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

une collection

J'ai essayé de créer une AllClocksressource de collection (même si je n'ai aucune utilité pour une telle chose sur la page):

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

Comment obtenir une seule horloge basée sur l' API?

James A. Rosen
la source
IMHO il appartient à la collection. Quelque chose comme Collection # fetchOne (id, callback).
Julian Maicher le

Réponses:

26

Votre deuxième approche est celle que j'ai utilisée. Essayez d'ajouter ce qui suit à votre modèle d'horloge:

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

Cette approche suppose que vous avez implémenté des contrôleurs avec le hashbang dans votre URL comme ceci, http://www.mydomain.com/#clocks/123 , mais cela devrait fonctionner même si vous ne l'avez pas encore fait.

Andrew De Andrade
la source
3
Il existe un moyen d'éviter cela, comme expliqué dans la documentation du modèle Backbone documentcloud.github.com/backbone/#Model-url
makevoid
@makevoid votre je ne pourrais pas faire fonctionner l'exemple que vous fournissez dans le script coffee ou celui de la documentation, l'exemple d'Andrew fonctionne, pourriez-vous fournir un exemple avec foo.url (), cela me dit toujours qu'il n'y a pas d'url de fonction.
Roberto Alarcon du
@makevoid, il semble que la méthode à laquelle vous faites référence ne fonctionne que si le modèle a été créé dans une collection. Remarquez la collection dans [collection.url]/[id].
Steven Devijver
@makevoid pouvez-vous s'il vous plaît fournir un lien de travail? malheureusement, celui-ci est cassé pour le moment
AlexNikolaev94
voici le lien de travail (ils ont déplacé le doc! wow, 5 ans passés, bon sang): backbonejs.org/#Model-url - @StevenDevijver est correct
makevoid
137

Essayez de spécifier urlRoot dans le modèle:

À partir de la documentation:

var Book = Backbone.Model.extend({urlRoot : '/books'});
var solaris = new Book({id: "1083-lem-solaris"});
solaris.fetch();
Hernan S.
la source
2
C'est bien, mais parfois vous ne voulez pas réinstaurer le modèle. Si vous voulez rechercher un produit spécifique contre le même modèle, vous pouvez faire un ensemble silencieux: currentBook.set('id', 13423, {silent:true}). Cela fonctionne aussi, mais je ne sais pas pourquoi:currentBook.id = 13423
SimplGy
1
@SimplGy qui fonctionne car model.idest essentiellement synonyme de model.attributes.id. Si vous appelez model.set('id'), Backbone définit model.idce que vous avez spécifié. Et model.idc'est ce qui est utilisé lors de la création de l'URL spécifique au modèle.
Lambart
26

Je recommande personnellement, en suivant la documentation de la méthode Model # url

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

dans votre collection, n'oubliez pas d'ajouter l'url de la collection:

url: "/models"

et dans la fonction d'initialisation de votre vue, faites:

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

de cette façon, backbone fera une requête ajax en utilisant cette URL:

"/models/1"

votre modèle sera mis à jour et la vue sera rendue, sans modifier Collection # url ou Model # urlRoot

Remarque: désolé, cet exemple est sorti dans le script coffee, mais vous pouvez facilement le traduire en js en ajoutant des instructions var

fairevoid
la source
Apparemment, cela ne fonctionne pas. N'appelle même pas le serveur lors de l'appel de fetch dans le modèle (ni dans la collection)
Ricardo Amores
Cela a l'air bien, mais la ligne de collection semble maladroite dans les cas où nous n'avons pas vraiment besoin de la collection.
Dingle
je ne pouvais pas faire fonctionner cela: this.model.get ('field'). On dirait que le modèle est créé sous-objet
Muhaimin
1
this.model.bind ("change", this.render, this) a bien fonctionné pour moi
dmi3y
1
@UlysseBN oui (c'était l'année 2011), vous pouvez ajouter des instructions var, {}à l'intérieur des ()'s pour les objets passés et en option et à ;la fin des lignes
makevoid
12
var Person = Backbone.Model.extend({urlRoot : '/person/details'});
var myName = new Person({id: "12345"});
myName.fetch();

En conséquence, vous faites une demande Ajax sur le

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

et vous avez la réponse JSON de retour.

Enjoiiii !!!

Ankit Garg
la source
2
c'est la même solution que @Hernan
Brenden
0

... et faites-le si vous ne voulez pas la barre oblique de fin sur le modèle urlRoot:

    url : function() {                        
        return this.urlRoot + this.id;
    },
4m1r
la source
0

Vous devriez probablement accéder à l'objet via une collection et le conserver tout le temps dans la collection. Voici comment faire:

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

var allClocks = new AllClocks();
my_clock = allClocks.add({id: 123});
my_clock.fetch()
ssobczak
la source
2
Tu ne sais pas ça. Peut-être qu'il n'a besoin que d'une seule horloge. Supposons que je veuille présenter à un client un seul modèle d'enregistrement d'utilisateur? Doit-il également avoir accès à une collection de tous les utilisateurs? Parfois, les gens ont juste besoin de quelques conseils tout en essayant de garder leur cas d'utilisation privé. Il suffit de répondre.
Adrian Bartholomew
0

Je veux utiliser l'URL RESTful, mais je ne comprends pas pourquoi «postId» ne peut pas être ajouté à l'URL de base.

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());

Ensuite, je sais seulement après avoir défini 'idAttribute' comme 'postId' dans Model que je peux obtenir la bonne URL. comme ça:

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