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


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.