Как мне получить одну модель в Backbone?

93

У меня есть Clockмодель в Backbone:

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

Я пытаюсь получить экземпляр, в котором есть последняя информация /clocks/123. Некоторые вещи, которые я пробовал:

метод уровня "класса"

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

создание экземпляра, а затем его вызов fetch:

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

Коллекция

Я попытался создать AllClocksресурс коллекции (хотя мне это не нужно на странице):

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

Как мне получить только одни часы с поддержкой API?

Джеймс А. Розен
источник
ИМХО он принадлежит к коллекции. Что-то вроде Collection # fetchOne (id, callback).
Джулиан Майчер

Ответы:

26

Ваш второй подход - это подход, который я использовал. Попробуйте добавить в свою модель часов следующее:

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

Этот подход предполагает, что вы реализовали контроллеры с хэш-бангом в своем URL-адресе, например http://www.mydomain.com/#clocks/123 , но он должен работать, даже если вы еще этого не сделали.

Эндрю Де Андраде
источник
3
Есть способ избежать этого, как описано в документации Backbone Model documentcloud.github.com/backbone/#Model-url
makevoid
@makevoid ваш Я не смог заставить работать пример, который вы предоставляете в сценарии кофе или тот, который в документации, пример Эндрю работает, не могли бы вы предоставить и пример с foo.url (), он всегда говорит мне, что нет URL-адреса функции.
Роберто Аларкон,
@makevoid кажется, что метод, о котором вы говорите, работает, только если модель была создана в коллекции. Обратите внимание на коллекцию в формате [collection.url]/[id].
Стивен Девиджвер
@makevoid, пожалуйста, предоставьте рабочую ссылку? к сожалению, этот пока сломан
AlexNikolaev94 06
вот рабочая ссылка (они переместили документ! Вау, прошло 5 лет, блин): backbonejs.org/#Model-url - @StevenDevijver верен
makevoid
137

Попробуйте указать urlRoot в модели:

Из документов:

var Book = Backbone.Model.extend({urlRoot : '/books'});
var solaris = new Book({id: "1083-lem-solaris"});
solaris.fetch();
Эрнан С.
источник
2
Это хорошо, но иногда вы не хотите воссоздавать модель. Если вы хотите , чтобы принести конкретный пункт против той же модели, вы можете сделать бесшумный набор: currentBook.set('id', 13423, {silent:true}). Это тоже работает, но я не уверен, почему:currentBook.id = 13423
SimplGy
1
@SimplGy, который работает, потому что model.idпо сути является синонимом model.attributes.id. Если вы звоните model.set('id'), Backbone устанавливает model.idвсе, что вы указали. И model.idэто то, что используется при создании URL-адреса для конкретной модели.
Lambart
26

Я лично рекомендую, следуя документации метода URL-адреса модели #

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

в вашей коллекции не забудьте добавить URL-адрес коллекции:

url: "/models"

и в вашей функции инициализации View выполните:

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

таким образом магистраль будет выполнять запрос ajax, используя этот URL:

"/models/1"

ваша модель будет обновлена, и представление будет отображаться без изменения Collection # url или Model # urlRoot

примечание: извините, этот пример появился в сценарии кофе, но вы можете легко перевести его на js, добавив операторы var

makevoid
источник
По-видимому, это не работает. Даже не обращается к серверу при вызове fetch в модели (или коллекции)
Рикардо Аморес,
Выглядит неплохо, но строка коллекции выглядит неудобно в тех случаях, когда она действительно не нужна.
Дингл
я не мог заставить это работать: this.model.get ('field'). Похоже, модель создана
подобъектом
1
this.model.bind ("изменить", this.render, this) хорошо сработал для меня
dmi3y 03
1
@UlysseBN да (был 2011 год), вы можете добавить операторы var {}внутри ()'s для переданных объектов и, необязательно, ;в конец строк
makevoid
12
var Person = Backbone.Model.extend({urlRoot : '/person/details'});
var myName = new Person({id: "12345"});
myName.fetch();

В результате вы делаете запрос Ajax на

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

и вы получили ответ в формате JSON.

Enjoyiiii !!!

Анкит Гарг
источник
2
это то же самое решение, что и @Hernan
Brenden
0

... и сделайте это, если вам не нужна завершающая косая черта в urlRoot модели:

    url : function() {                        
        return this.urlRoot + this.id;
    },
4м1р
источник
0

Вероятно, вам следует обращаться к объекту через коллекцию и постоянно хранить его в коллекции. Вот как это сделать:

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

var allClocks = new AllClocks();
my_clock = allClocks.add({id: 123});
my_clock.fetch()
ссобчак
источник
2
Вы этого не знаете. Может быть, ему нужны только часы. Предположим, я хочу представить клиенту единственную модель записи пользователя? Должен ли он иметь доступ и к Коллекции всех пользователей? Иногда людям просто нужен совет, пытаясь сохранить конфиденциальность своего использования. Просто ответ.
Адриан Бартоломью
0

Я хочу использовать URL RESTful, но не могу понять, почему нельзя добавить postId к базовому 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());

Тогда я знаю, что только после того, как я установил idAttribute как postId в модели, смогу ли я получить правильный URL. как это:

var PostModel = Backbone.Model.extend({
    idAttribute: 'postId',
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});
Араэль
источник