Backbone'da tek bir modeli nasıl getirebilirim?


93

ClockBackbone'da bir modelim var :

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

En son bilgileri içeren bir örneğini almaya çalışıyorum /clocks/123. Denediğim bazı şeyler:

"sınıf" düzeyinde bir yöntem

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

bir örnek oluşturma ve ardından fetchonu çağırma :

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

bir koleksiyon

Bir AllClockskoleksiyon kaynağı oluşturmayı denedim (sayfada böyle bir şeyi kullanmama rağmen):

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

Nasıl Sadece alırım bir API destekli Saat?


IMHO koleksiyona aittir. Collection # fetchOne (id, callback) gibi bir şey.
Julian Maicher

Yanıtlar:


26

İkinci yaklaşımınız benim kullandığım yaklaşımdır. Aşağıdakileri Saat modelinize eklemeyi deneyin:

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

Bu yaklaşım, http://www.mydomain.com/#clocks/123 gibi URL'nizde hashbang ile denetleyicileri uyguladığınızı varsayar , ancak henüz yapmamışsanız bile çalışmalıdır.


3
Omurga Modeli belgelerinde açıklandığı gibi bundan kaçınmanın bir yolu var: documentcloud.github.com/backbone/#Model-url
makevoid

@makevoid your Ben kahve senaryosunda veya dokümantasyonda sağladığınız örnekte çalışamadım, Andrew örneği çalışıyor, foo.url () ile sağlayabilir ve örnek verebilir misiniz, bana her zaman url işlevi olmadığını söyler.
Roberto Alarcon

@makevoid, bahsettiğiniz yöntem sadece model bir koleksiyonda oluşturulmuşsa işe yarıyor gibi görünüyor. İçindeki koleksiyona dikkat edin [collection.url]/[id].
Steven Devijver

@makevoid lütfen çalışan bir bağlantı sağlayabilir misiniz? maalesef bu şimdilik bozuk
AlexNikolaev94

işte çalışma bağlantısı ( belgeyi taşıdılar ! vay, 5 yıl geçti, tanrım ): backbonejs.org/#Model-url - @StevenDevijver doğru
makevoid

137

Modelde urlRoot belirtmeyi deneyin :

Dokümanlardan:

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

2
Bu iyidir, ancak bazen modeli yeniden canlandırmak istemezsiniz. Aynı modele karşı belirli bir öğeyi almak için isterseniz, sessiz bir set yapabilirsiniz: currentBook.set('id', 13423, {silent:true}). Bu da işe yarıyor, ancak neden olduğundan emin değilim:currentBook.id = 13423
SimplGy

1
@SimplGy model.idaslında eşanlamlı olduğu için çalışıyor model.attributes.id. Eğer çağırırsanız model.set('id'), Backbone model.idbelirttiğiniz şeye ayarlanır . Ve model.idmodele özgü bir URL oluştururken kullanılan alır budur.
Lambart

26

Model # url yöntemi belgelerini takip ederek şahsen tavsiye ederim

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

koleksiyonunuza koleksiyon url'sini eklemeyi unutmayın:

url: "/models"

ve Görünümünüzün başlatma işlevinde şunları yapın:

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

bu şekilde, omurga bu url'yi kullanarak bir ajax isteğinde bulunacaktır:

"/models/1"

Koleksiyon # url veya Model # urlRoot değiştirilmeden modeliniz güncellenecek ve görünüm işlenecektir.

not: özür dilerim bu örnek kahve betiğinde ortaya çıktı, ancak bunu kolayca js'ye çevirebilir ve var ifadeleri ekleyebilirsiniz


Görünüşe göre bu işe yaramıyor. Modelde (veya koleksiyonda) getirmeyi ararken sunucuya bir çağrı bile yapmayın
Ricardo Amores

Bu iyi görünüyor, ancak koleksiyona gerçekten ihtiyacımız olmadığı durumlarda koleksiyon hattı garip görünüyor.
Dingle

bunu çalıştıramadım: this.model.get ('alan'). Model alt nesne oluşturulmuş gibi görünüyor
Muhaimin

1
this.model.bind ("change", this.render, this) benim için iyi çalıştı
dmi3y

1
@UlysseBN evet (2011 yılıydı), aktarılan nesneler için 's' ların {}içine ve satırların sonundaki ()isteğe bağlı ;reklamın içine var ifadeleri ekleyebilirsiniz
makevoid

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

Sonuç olarak, bir Ajax isteğinde bulunursunuz.

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

ve JSON yanıtını geri aldınız.

Enjoiiii !!!


2
bu, @Hernan ile aynı çözüm
Brenden

0

... ve urlRoot modelinin sonundaki eğik çizgiyi istemiyorsanız bunu yapın:

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

0

Muhtemelen nesneye bir koleksiyon aracılığıyla erişmeli ve onu her zaman koleksiyonda tutmalısınız. Böyle yapılır:

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

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

2
Bunu bilmiyorsun. Belki tek ihtiyacı olan bir Saattir. Bir müşteriye tek bir Kullanıcı kaydı Modeli sunmak istediğimi varsayalım. Tüm Kullanıcılardan oluşan bir Koleksiyona da erişimi olmalı mı? Bazen insanlar, kullanım durumlarını gizli tutmaya çalışırken bazı tavsiyelere ihtiyaç duyar. Sadece cevap.
Adrian Bartholomew

0

RESTful url kullanmak istiyorum, ancak 'postId'nin neden temel url'ye eklenemediğini anlayamadım.

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

O zaman sadece Model'de 'idAttribute'u' postId 'olarak ayarladıktan sonra doğru url'yi alabilirim. bunun gibi:

var PostModel = Backbone.Model.extend({
    idAttribute: 'postId',
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.