Jak mogę pobrać pojedynczy model w Backbone?

93

Mam Clockmodel w Backbone:

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

Próbuję uzyskać przykład tego, który zawiera najnowsze informacje /clocks/123. Kilka rzeczy, których próbowałem:

metoda na poziomie „klasy”

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

tworzenie instancji, a następnie wywoływanie fetchjej:

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

kolekcja

Próbowałem utworzyć AllClockszasób kolekcji (mimo że nie mam pożytku z czegoś takiego na stronie):

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

Jak uzyskać jeden zegar wspierany przez API?

James A. Rosen
źródło
IMHO należy do kolekcji. Coś w rodzaju Collection # fetchOne (id, callback).
Julian Maicher

Odpowiedzi:

26

Twoje drugie podejście to podejście, którego użyłem. Spróbuj dodać następujące elementy do swojego modelu Zegara:

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

To podejście zakłada, że ​​zaimplementowałeś kontrolery z hashbangiem w swoim adresie URL, jak na przykład http://www.mydomain.com/#clocks/123 , ale powinno działać nawet jeśli jeszcze tego nie zrobiłeś.

Andrew De Andrade
źródło
3
Istnieje sposób, aby tego uniknąć, jak wyjaśniono w dokumentacji modelu szkieletowego documentcloud.github.com/backbone/#Model-url
makevoid
@makevoid your I nie mogłem zrobić pracy przykład, który podajesz w skrypcie kawy lub ten w dokumentacji, przykład Andrew działa, czy możesz podać i przykład z foo.url (), zawsze mówi mi, że nie ma adresu URL funkcji.
Roberto Alarcon
@makevoid wygląda na to, że metoda, do której się odnosisz, działa tylko wtedy, gdy model został utworzony w kolekcji. Zwróć uwagę na kolekcję w [collection.url]/[id].
Steven Devijver
@makevoid czy możesz podać działający link? niestety ten na razie jest zepsuty
AlexNikolaev94
oto działający link (przenieśli dokument! wow, minęło 5 lat, rany): backbonejs.org/#Model-url - @StevenDevijver is correct
makevoid
137

Spróbuj określić urlRoot w modelu:

Z dokumentów:

var Book = Backbone.Model.extend({urlRoot : '/books'});
var solaris = new Book({id: "1083-lem-solaris"});
solaris.fetch();
Hernan S.
źródło
2
To dobrze, ale czasami nie chcesz przywracać modelu. Jeśli chcesz, aby pobrać element specyficzny wobec tego samego modelu, można zrobić cichy zestaw: currentBook.set('id', 13423, {silent:true}). To też działa, ale nie jestem pewien, dlaczego:currentBook.id = 13423
SimplGy
1
@SimplGy, które działa, ponieważ model.idjest zasadniczo synonimem model.attributes.id. Jeśli zadzwonisz model.set('id'), Backbone ustawia się model.idna wszystko, co podałeś. I model.idto jest używane podczas tworzenia adresu URL specyficznego dla modelu.
Lambart
26

Osobiście polecam, postępując zgodnie z dokumentacją metody Model # url

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

w swojej kolekcji pamiętaj o dodaniu adresu URL kolekcji:

url: "/models"

i w funkcji inicjalizacji swojego View wykonaj:

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

w ten sposób szkielet wykona żądanie AJAX przy użyciu tego adresu URL:

"/models/1"

Twój model zostanie zaktualizowany, a widok wyrenderowany, bez modyfikowania Collection # url lub Model # urlRoot

uwaga: przepraszam, że ten przykład pojawił się w skrypcie kawy, ale można go łatwo przetłumaczyć na js dodając instrukcje var

makevoid
źródło
Najwyraźniej to nie działa. Nawet nie nawiązuje połączenia z serwerem podczas wywoływania funkcji pobierania w modelu (ani kolekcji)
Ricardo Amores
Wygląda to dobrze, ale linia kolekcji wygląda niezręcznie w przypadkach, gdy naprawdę nie potrzebujemy kolekcji.
Dingle
nie mogłem uruchomić tego: this.model.get („pole”). Wygląda na to, że model jest utworzony podobiektem
Muhaimin
1
this.model.bind ("change", this.render, this) działało dobrze dla mnie
dmi3y
1
@UlysseBN tak (to był rok 2011), możesz dodać instrukcje var, {}wewnątrz ()dla przekazanych obiektów i opcjonalnie ;ad na końcu linii
makevoid
12
var Person = Backbone.Model.extend({urlRoot : '/person/details'});
var myName = new Person({id: "12345"});
myName.fetch();

W rezultacie wysyłasz żądanie Ajax na

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

i masz z powrotem odpowiedź JSON.

Enjoiiii !!!

Ankit Garg
źródło
2
jest to to samo rozwiązanie, co @Hernan
Brenden
0

... i zrób to, jeśli nie chcesz, aby końcowy ukośnik w modelu urlRoot:

    url : function() {                        
        return this.urlRoot + this.id;
    },
4m1r
źródło
0

Prawdopodobnie powinieneś uzyskiwać dostęp do obiektu przez kolekcję i przechowywać go w kolekcji przez cały czas. Oto jak to zrobić:

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

var allClocks = new AllClocks();
my_clock = allClocks.add({id: 123});
my_clock.fetch()
ssobczak
źródło
2
Ty tego nie wiesz. Może wszystko, czego potrzebuje, to jeden Zegar. Przypuśćmy, że chcę przedstawić klientowi pojedynczy model rekordu użytkownika? Czy powinien mieć również dostęp do zbioru wszystkich użytkowników? Czasami ludzie po prostu potrzebują porady, starając się zachować prywatność swojego przypadku. Tylko odpowiedz.
Adrian Bartholomew
0

Chcę użyć RESTful url, ale nie mogłem zrozumieć, dlaczego „postId” nie może zostać dodane do podstawowego adresu URL.

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

Wtedy wiem, że dopiero po ustawieniu „idAttribute” jako „postId” w modelu mogę uzyskać właściwy adres URL. lubię to:

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