Подтвердить что ты не робот

Backbone.js изменить параметр url для модели и выборки не обновляет данные

У меня есть следующая модель:

window.MyModel = Backbone.Model.extend({
     initialize: function(props){
          this.url = props.url;
     } 

     parse: function(){

          // @override- parsing data fetched from URL
     }


});

 // instantiate
  var mod = new MyModel({url: 'some/url/here'});

Я использую эту глобальную переменную 'mod' для извлечения некоторых данных в эту модель из бэкэнд.

 // fetch

 mod.fetch({
       success: function(){ ...},
       error: ...

 });

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

  mod.fetch({ 
       data: {url:'/some/other/url'},
       postData: true,
       success: function(){ //process data},
       error: ...
  });


 mod.set({url: '/some/other/url'});
 // called fetch() without data: and postData: attributes as mentioned in previous

Как установить URL-адрес моей модели, чтобы я мог вызвать fetch(), и он извлекает данные из обновленного URL-адреса? Я что-то упускаю. Спасибо за любые указатели..

ОБНОВЛЕНИЕ 1. В принципе, я не могу получить обновленные значения, если я сделал

    model.set({url: 'new value'}); 

за которым следует

    model.fetch();

'model' - глобальная переменная. Создание нового экземпляра "модельных" работ:

    model = new Model({url:'/some/other/url'}); 
    model.fetch();

однако работает по мере необходимости. Означает ли это, что экземпляр модели постоянно привязан к URL-адресу и не может быть reset?

ОТВЕТ НА МОЙ ВОПРОС в ОБНОВЛЕНИИ 1 Экземпляр модели не привязан к URL-адресу постоянно. Это может быть reset динамически. Пожалуйста, прочитайте подробное объяснение @tkone, а затем решение @fguillens для лучшего понимания.

4b9b3361

Ответ 1

После того, как вы поняли объяснение @tkone...

Если вы все еще хотите иметь динамический Model.url, вы всегда можете отложить его конструкцию для запуска, попробуйте следующее:

window.MyModel = Backbone.Model.extend({
  url: function(){
    return this.instanceUrl;
  },
  initialize: function(props){
    this.instanceUrl = props.url;
  } 
}

Ответ 2

Хорошо, ответ здесь заключается в том, что вы хотите сделать:

mod.url = '/some/other/url'

URL-адрес не является частью экземпляра самой модели, а скорее атрибутом объекта MyModel, из которого вы создаете экземпляр модели. Поэтому вы просто установите его так, как будто это было обычное свойство JavaScript-объекта. set используется только тогда, когда данные, которые вы устанавливаете (или, наоборот, получаете с помощью get), на самом деле являются атрибутом данных, которые вы хотите отправить/получить с сервера.

Но почему вы меняете URL-адрес, это вопрос, который мы должны задать. Идея системы модели/коллекции Backbone заключается в том, что вы говорите с конечной точкой REST, и каждая модель имеет соответствующую конечную точку.

Как и у вас есть блог, и этот блог имеет объект "entry", доступный по адресу:

/rest/entry/

И у вас есть модель Backbone для Entry:

Entry = Backbone.Model.extend({urlBase: '/rest/entry'});

Теперь, когда вы save или fetch Магистраль знает, как это работает.

Так как вы создаете новую модель:

e = new Entry();
e.set({title: "my blog rulez", body: "this is the best blog evar!!!!1!!"});
e.save();

Это позволит сделать Backbone запрос HTTP POST на /rest/entry с телом:

{
  "title": "my blog rulez",
  "body": "this is the best blog evar!!!!1!!"
}

(Когда вы делаете свой mod.set({url: '/some/other/url'});, вы фактически добавляете поле с именем url в набор данных, поэтому сервер отправит "url": "/some/other/url" как часть этого тела JSON POST выше:

{
  "title": "my blog rulez",
  "body": "this is the best blog evar!!!!1!!",
  "url": "/some/other/url" 
}

Затем сервер будет отвечать с ответом HTTP 200 (или 201) с той же моделью, только с прикрепленным, например, и идентификатором:

{
  "id": 1,
  "title": "my blog rulez",
  "body": "this is the best blog evar!!!!1!!"
}

И это не то, что вы ищете, верно?)

Теперь у вас есть эта модель, и у нее есть идентификатор. Это означает, что если вы измените его:

e.set('title', 'my blog is actually just ok');
e.save()

Массив теперь делает запрос HTTP PUT на /rest/entry/1 для обновления ресурса на сервере.

Сервер видит, что вы говорите об идентификаторе 1 на конечной точке /rest/entry/, поэтому знает, как обновить существующую запись (и отправить обратно HTTP 200).

TL; DR

Не меняйте URL-адрес. Создайте новую модель для новой части данных.

Ответ 3

model.urlRoot = "/your/url"

ИЛИ

model.urlRoot = function(){ return "/your/url"; }

ИЛИ

model.url = "/your/url"

ИЛИ

model.url = function(){ return "/your/url"; }

Значение по умолчанию 'url' объекта Backbone.Model выглядит следующим образом. Backbone.js doc говорит:

URL-адрес по умолчанию для представления модели на сервере - если вы используете методы Backbone restful, переопределите это, чтобы изменить конечную точку, которая будет вызываться.

url: function() {
  var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError();
  if (this.isNew()) return base;
  return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
},

Ясно, что сначала он получает значение urlRoot, если оно недоступно, оно будет искать URL-адрес коллекции, к которой принадлежит модель. Определяя urlRoot, а не url, есть преимущество отпадать обратно в url коллекции, если urlRoot имеет значение null.

Ответ 4

Вы можете установить url как параметр в функции fetch, например:

var mod = new MyModel();
mod.fetch({
   url: '/some/other/url',
   data: {}
});