Як отримати одну модель в основі?


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?


ІМХО він належить до колекції. Щось на зразок колекції # fetchOne (ідентифікатор, зворотний виклик).
Джуліан Майхер,

Відповіді:


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
Існує спосіб уникнути цього, як пояснено в документації щодо моделі
хребта

@makevoid your Я не міг зробити роботу прикладом, який ви подаєте в сценарії кави або наведеним у документації, працює приклад Andrew, не могли б ви надати і приклад з foo.url (), це завжди говорить мені, що немає функції url.
Роберто Аларкон,

@makevoid здається, що метод, про який ви посилаєтесь, працює лише тоді, коли модель була створена в колекції. Помітьте колекцію в [collection.url]/[id].
Стівен Девівер

@makevoid чи можете ви надати робоче посилання? на жаль, цей поки що не працює
AlexNikolaev94

ось робоче посилання (вони перенесли документ! вау, минуло 5 років, боже): backbonejs.org/#Model-url - правильним є
@StevenDevijver

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-адреси для конкретної моделі.
Ламбарт

26

Я особисто рекомендую, дотримуючись документації до методу url #

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

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

url: "/models"

і у функції ініціалізації перегляду виконайте:

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

таким чином магістраль зробить запит ajax за допомогою цієї URL-адреси:

"/models/1"

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

Примітка: Вибачте, цей приклад вийшов у сценарії кави, але ви можете легко перекласти його на js, додаючи var заяви


Мабуть, це не працює. Навіть не здійснюйте дзвінок на сервер, коли дзвоніть за вибором у моделі (ні колекцією)
Рікардо Аморес

Це виглядає чудово, але колекційна лінія виглядає незручно у випадках, коли нам насправді не потрібна колекція.
Дінгл

я не міг змусити це працювати: this.model.get ('поле'). Схоже, модель створена під об’єктом
Мухаїмін,

1
this.model.bind ("change", this.render, this) добре для мене
спрацював

1
@UlysseBN так (був 2011 рік), ви можете додати оператори var, {}всередину ()'' для переданих об'єктів та необов'язково ;до кінця рядків
уникайте

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.

Насолоджуйтесь !!!


2
це те саме рішення, що і @Hernan
Brenden

0

... і зробіть це, якщо ви не хочете косої косої риси на моделі urlRoot:

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

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

Я хочу використовувати RESTful url, але я не міг зрозуміти, чому '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' у Model, я можу отримати правильну URL-адресу. подобається це:

var PostModel = Backbone.Model.extend({
    idAttribute: 'postId',
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.