Làm cách nào để tìm nạp một mô hình duy nhất trong Backbone?


93

Tôi có một Clockmô hình trong Backbone:

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

Tôi đang cố gắng lấy một phiên bản có thông tin mới nhất từ ​​đó /clocks/123. Một số điều tôi đã thử:

một phương thức cấp "lớp"

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

tạo một thể hiện và sau đó gọi fetchnó:

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

một bộ sưu tập

Tôi đã thử tạo một AllClockstài nguyên bộ sưu tập (ngay cả khi tôi không sử dụng những thứ như vậy trên trang):

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

Làm cách nào để tôi chỉ nhận được một Đồng hồ được hỗ trợ bởi API?


IMHO nó thuộc về bộ sưu tập. Một cái gì đó như Collection # fetchOne (id, callback).
Julian Maicher

Câu trả lời:


26

Cách tiếp cận thứ hai của bạn là cách tiếp cận mà tôi đã sử dụng. Hãy thử thêm những thứ sau vào mẫu Đồng hồ của bạn:

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

Cách tiếp cận này giả định rằng bạn đã triển khai bộ điều khiển với hashbang trong URL của mình, http://www.mydomain.com/#clocks/123 , nhưng nó sẽ hoạt động ngay cả khi bạn chưa thực hiện.


3
Có một cách để tránh điều này như được giải thích trong tài liệu Backbone Mẫu documentcloud.github.com/backbone/#Model-url
makevoid

@makevoid your Tôi không thể thực hiện ví dụ bạn cung cấp trong tập lệnh cà phê hoặc ví dụ trong tài liệu, ví dụ Andrew hoạt động, bạn có thể cung cấp và ví dụ với foo.url () không, nó luôn cho tôi biết rằng không có url chức năng.
Roberto Alarcon

@makevoid có vẻ như phương pháp bạn đang đề cập chỉ hoạt động nếu mô hình đã được tạo trong bộ sưu tập. Chú ý bộ sưu tập trong [collection.url]/[id].
Steven Devijver

@makevoid bạn có thể vui lòng cung cấp liên kết làm việc được không? không may, điều này được chia cho bây giờ
AlexNikolaev94

đây là liên kết làm việc (họ chuyển doc wow, 5 năm trôi qua, geez!): backbonejs.org/#Model-url - @StevenDevijver là đúng
makevoid

137

Hãy thử chỉ định urlRoot trong mô hình:

Từ các tài liệu:

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

2
Điều này là tốt, nhưng đôi khi bạn không muốn khôi phục mô hình. Nếu bạn muốn lấy một mục cụ thể chống lại cùng một mô hình, bạn có thể làm một bộ im lặng: currentBook.set('id', 13423, {silent:true}). Điều này cũng hoạt động, nhưng tôi không chắc tại sao:currentBook.id = 13423
SimplGy

1
@SimplGy hoạt động vì model.idvề cơ bản đồng nghĩa với model.attributes.id. Nếu bạn gọi model.set('id'), Backbone sẽ đặt model.idthành bất kỳ thứ gì bạn đã chỉ định. Và model.idlà những gì được sử dụng khi tạo URL dành riêng cho mô hình.
Lambart

26

Cá nhân tôi khuyên bạn nên làm theo tài liệu phương pháp url Model #

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

trong bộ sưu tập của bạn, hãy nhớ thêm url bộ sưu tập:

url: "/models"

và trong chức năng khởi tạo Chế độ xem của bạn thực hiện:

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

theo cách này, đường trục sẽ thực hiện một yêu cầu ajax bằng cách sử dụng url này:

"/models/1"

mô hình của bạn sẽ được cập nhật và chế độ xem được hiển thị mà không sửa đổi url Bộ sưu tập # hoặc Mô hình # urlRoot

lưu ý: xin lỗi, ví dụ này xuất hiện trong coffee script, nhưng bạn có thể dễ dàng dịch nó sang js khi thêm câu lệnh var


Rõ ràng điều này không hoạt động. Thậm chí không thực hiện cuộc gọi đến máy chủ khi gọi lấy trong mô hình (hay bộ sưu tập)
Ricardo Amores

Điều này trông ổn, nhưng dòng thu thập có vẻ khó xử trong trường hợp chúng tôi không thực sự cần bộ sưu tập.
Dingle

tôi không thể làm cho cái này hoạt động: this.model.get ('field'). Có vẻ như mô hình được tạo đối tượng phụ
Muhaimin

1
this.model.bind ("change", this.render, this) hoạt động tốt đối với tôi
dmi3y

1
@UlysseBN vâng (là năm 2011), bạn có thể thêm báo cáo var, {}bên trong ()'s cho các đối tượng thông qua và tùy chọn ;quảng cáo khi kết thúc dòng
makevoid

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

Do đó, bạn thực hiện một yêu cầu Ajax trên

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

và bạn có phản hồi JSON trở lại.

Thích quáii !!!


2
đây là giải pháp tương tự như @Hernan
Brenden

0

... và làm điều này nếu bạn không muốn có dấu gạch chéo trên mô hình urlRoot:

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

0

Bạn có thể nên truy cập vào đối tượng máng một bộ sưu tập và giữ nó trong bộ sưu tập mọi lúc. Đây là cách thực hiện:

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

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

2
Bạn không biết điều đó. Có lẽ tất cả những gì anh ta yêu cầu là một chiếc Đồng hồ. Giả sử tôi muốn giới thiệu cho khách hàng một Mẫu bản ghi Người dùng duy nhất? Anh ta cũng có quyền truy cập vào Bộ sưu tập của tất cả Người dùng? Đôi khi dân gian chỉ cần một số lời khuyên trong khi cố gắng giữ bí mật về usecase của họ. Chỉ cần trả lời.
Adrian Bartholomew

0

Tôi muốn sử dụng url RESTful, nhưng tôi không hiểu tại sao không thể thêm 'postId' vào url cơ sở.

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

Sau đó, tôi biết chỉ sau khi tôi đặt 'idAttribute' là 'postId' trong Mô hình, tôi mới có thể nhận được url phù hợp. như thế này:

var PostModel = Backbone.Model.extend({
    idAttribute: 'postId',
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.