Come posso recuperare un singolo modello in Backbone?


93

Ho un Clockmodello in Backbone:

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

Sto cercando di ottenere un'istanza di quello che ha le ultime informazioni da /clocks/123. Alcune cose che ho provato:

un metodo a livello di "classe"

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

creando un'istanza e quindi richiamandola fetch:

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

una collezione

Ho provato a creare una AllClocksrisorsa di raccolta (anche se non ho alcuna utilità per una cosa del genere nella pagina):

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

Come posso ottenere solo un orologio supportato da API?


IMHO appartiene alla collezione. Qualcosa come Collection # fetchOne (id, callback).
Julian Maicher

Risposte:


26

Il tuo secondo approccio è l'approccio che ho usato. Prova ad aggiungere quanto segue al tuo modello di orologio:

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

Questo approccio presuppone che tu abbia implementato controller con l'hashbang nel tuo URL in questo modo, http://www.mydomain.com/#clocks/123 , ma dovrebbe funzionare anche se non l'hai ancora fatto.


3
C'è un modo per evitarlo, come spiegato nella documentazione del modello Backbone documentcloud.github.com/backbone/#Model-url
makevoid

@makevoid your Non ho potuto far funzionare l'esempio che fornisci nello script coffee o quello nella documentazione, l'esempio Andrew funziona, potresti fornire un esempio con foo.url (), mi dice sempre che non c'è l'URL della funzione.
Roberto Alarcon

@makevoid sembra che il metodo a cui ti riferisci funzioni solo se il modello è stato creato in una collezione. Notare la raccolta in [collection.url]/[id].
Steven Devijver

@makevoid puoi fornire un link funzionante? sfortunatamente, questo è rotto per ora
AlexNikolaev94

ecco il link funzionante (hanno spostato il documento! wow, sono passati 5 anni, accidenti): backbonejs.org/#Model-url - @StevenDevijver è corretto
makevoid

137

Prova a specificare urlRoot nel modello:

Dai documenti:

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

2
Questo va bene, ma a volte non vuoi reintegrare il modello. Se si vuole recuperare un elemento specifico contro lo stesso modello, è possibile fare una serie silenzioso: currentBook.set('id', 13423, {silent:true}). Anche questo funziona, ma non sono sicuro del perché:currentBook.id = 13423
SimplGy

1
@SimplGy che funziona perché model.idè essenzialmente sinonimo di model.attributes.id. Se chiami model.set('id'), Backbone si imposta model.idsu quello che hai specificato. Ed model.idè ciò che viene utilizzato durante la creazione dell'URL specifico del modello.
Lambart

26

Personalmente raccomando, seguendo la documentazione del metodo URL modello #

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

nella tua raccolta ricordati di aggiungere l'URL della collezione:

url: "/models"

e nella funzione di inizializzazione della vista fai:

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

in questo modo backbone eseguirà una richiesta ajax utilizzando questo URL:

"/models/1"

il modello verrà aggiornato e la vista verrà renderizzata, senza modificare Collection # url o Model # urlRoot

nota: scusa questo esempio è uscito con lo script coffee, ma puoi facilmente tradurlo in js aggiungendo istruzioni var


Apparentemente questo non funziona. Non effettua nemmeno una chiamata al server quando chiama fetch nel modello (né nella raccolta)
Ricardo Amores

Sembra a posto, ma la linea di raccolta sembra scomoda nei casi in cui non abbiamo davvero bisogno della raccolta.
Dingle

non sono riuscito a farlo funzionare: this.model.get ('field'). Sembra che il modello sia stato creato come oggetto secondario
Muhaimin

1
this.model.bind ("change", this.render, this) ha funzionato bene per me
dmi3y

1
@UlysseBN sì (era l'anno 2011), puoi aggiungere istruzioni var, {}all'interno di ()'s per gli oggetti passati e ;annuncio facoltativo alla fine delle righe
makevoid

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

Di conseguenza, fai una richiesta Ajax sul file

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

e hai indietro la risposta JSON.

Enjoiiii !!!


2
questa è la stessa soluzione di @Hernan
Brenden

0

... e fallo se non vuoi la barra finale sul modello urlRoot:

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

0

Probabilmente dovresti accedere all'oggetto tramite una raccolta e mantenerlo nella raccolta tutto il tempo. Così è come si fa:

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

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

2
Non lo sai. Forse tutto ciò che richiede è un orologio. Supponiamo di voler presentare a un cliente un unico modello di un record utente? Dovrebbe avere accesso anche a una raccolta di tutti gli utenti? A volte le persone hanno solo bisogno di qualche consiglio mentre cercano di mantenere privato il loro caso d'uso. Rispondi e basta.
Adrian Bartholomew

0

Voglio usare l'URL RESTful, ma non riesco a capire perché "postId" non può essere aggiunto all'URL di 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());

Quindi so che solo dopo aver impostato 'idAttribute' come 'postId' in Model posso ottenere l'URL corretto. come questo:

var PostModel = Backbone.Model.extend({
    idAttribute: 'postId',
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.