Bagaimana cara mengambil satu model di Backbone?


93

Saya memiliki Clockmodel di Backbone:

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

Saya mencoba mendapatkan contoh yang memiliki informasi terbaru dari /clocks/123. Beberapa hal yang saya coba:

metode tingkat "kelas"

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

membuat sebuah instance dan kemudian memanggilnya fetch:

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

koleksi

Saya mencoba membuat AllClockssumber daya koleksi (meskipun saya tidak menggunakan hal seperti itu di halaman):

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

Bagaimana cara mendapatkan satu Jam yang didukung API?


IMHO itu milik koleksi. Sesuatu seperti Collection # fetchOne (id, callback).
Julian Maicher

Jawaban:


26

Pendekatan kedua Anda adalah pendekatan yang telah saya gunakan. Coba tambahkan yang berikut ini ke model Jam Anda:

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

Pendekatan ini mengasumsikan bahwa Anda telah mengimplementasikan pengontrol dengan hashbang di URL Anda seperti, http://www.mydomain.com/#clocks/123 , tetapi seharusnya berfungsi bahkan jika Anda belum melakukannya.


3
Ada cara untuk menghindari ini seperti yang dijelaskan dalam dokumentasi Model Backbone documentcloud.github.com/backbone/#Model-url
makevoid

@makevoid Anda Saya tidak bisa membuat karya contoh yang Anda berikan di skrip kopi atau yang ada di dokumentasi, contoh Andrew bekerja, dapatkah Anda memberikan dan contoh dengan foo.url (), selalu beri tahu saya bahwa tidak ada url fungsi.
Roberto Alarcon

@makevoid tampaknya metode yang Anda maksud hanya berfungsi jika model telah dibuat dalam koleksi. Perhatikan koleksi di [collection.url]/[id].
Steven Devijver

@makevoid dapatkah Anda memberikan tautan yang berfungsi? sayangnya, yang ini rusak untuk saat ini
AlexNikolaev94

inilah tautan yang berfungsi (mereka memindahkan dokumen! wow, 5 tahun berlalu, ya ampun): backbonejs.org/#Model-url - @StevenDevijver benar
makevoid

137

Coba tentukan urlRoot dalam model:

Dari dokumen:

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

2
Ini bagus, tetapi terkadang Anda tidak ingin memulihkan model. Jika Anda ingin mengambil item tertentu terhadap model yang sama, Anda dapat melakukan set silent: currentBook.set('id', 13423, {silent:true}). Ini bekerja juga, tapi saya tidak yakin mengapa:currentBook.id = 13423
SimplGy

1
@SimplGy yang berfungsi karena model.idpada dasarnya identik dengan model.attributes.id. Jika Anda menelepon model.set('id'), Backbone mengatur model.idapa pun yang Anda tentukan. Dan model.idapa yang digunakan saat membuat URL khusus model.
Lambart

26

Saya pribadi merekomendasikan, mengikuti dokumentasi metode Model # url

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

dalam koleksi Anda, ingatlah untuk menambahkan url koleksi:

url: "/models"

dan dalam fungsi inisialisasi View Anda lakukan:

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

dengan cara ini tulang punggung akan melakukan permintaan ajax menggunakan url ini:

"/models/1"

model Anda akan diperbarui dan tampilan dirender, tanpa mengubah Collection # url atau Model # urlRoot

catatan: maaf contoh ini keluar dalam skrip kopi, tetapi Anda dapat dengan mudah menerjemahkannya ke js menambahkan pernyataan var


Rupanya ini tidak berhasil. Bahkan tidak membuat panggilan ke server saat memanggil ambil dalam model (atau koleksi)
Ricardo Amores

Ini terlihat bagus, tetapi garis koleksi terlihat canggung jika kita tidak benar-benar membutuhkan koleksinya.
Dingle

saya tidak bisa mendapatkan ini untuk bekerja: this.model.get ('field'). Sepertinya model dibuat sub objek
Muhaimin

1
this.model.bind ("change", this.render, this) bekerja dengan baik untuk saya
dmi3y

1
@UlysseBN ya (adalah tahun 2011), Anda dapat menambahkan pernyataan var, {}di dalam ()untuk objek yang dilewatkan dan ;iklan opsional di akhir baris
makevoid

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

Akibatnya, Anda membuat permintaan Ajax di

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

dan Anda mendapatkan tanggapan JSON kembali.

Enjoiiii !!!


2
ini adalah solusi yang sama dengan @Hernan
Brenden

0

... dan lakukan ini jika Anda tidak ingin garis miring pada model urlRoot:

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

0

Anda mungkin harus mengakses objek melalui koleksi dan menyimpannya dalam koleksi sepanjang waktu. Ini adalah cara untuk melakukannya:

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

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

2
Anda tidak tahu itu. Mungkin yang dia butuhkan hanyalah satu Jam. Misalkan saya ingin menyajikan klien dengan Model tunggal catatan Pengguna? Haruskah dia memiliki akses ke Koleksi semua Pengguna juga? Kadang-kadang orang hanya membutuhkan beberapa nasihat sambil mencoba merahasiakan kasus penggunaan mereka. Jawab saja.
Adrian Bartholomew

0

Saya ingin menggunakan url RESTful, tetapi saya tidak mengerti mengapa 'postId' tidak dapat ditambahkan ke url dasar.

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

Maka saya tahu hanya setelah saya menetapkan 'idAttribute' sebagai 'postId' di Model saya bisa mendapatkan url yang benar. seperti ini:

var PostModel = Backbone.Model.extend({
    idAttribute: 'postId',
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.