12

我有以下模型:

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并调用fetch来重用这个模型,但它不会以某种方式更新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 = new Model({url:'/some/other/url'}); 
    model.fetch();

但是,按要求工作。这是否意味着模型实例永久附加到 url 并且无法重置?

更新 1 中对我的问题的回答模型实例未永久附加到 url。它可以动态重置。请阅读@tkone 的详尽解释,然后阅读@fguillens 的解决方案以便更好地理解。

4

4 回答 4

24

在了解了@tkone 的解释之后......

如果您仍然想要动态Model.url,您总是可以将其构造延迟到运行时,试试这个:

window.MyModel = Backbone.Model.extend({
  url: function(){
    return this.instanceUrl;
  },
  initialize: function(props){
    this.instanceUrl = props.url;
  } 
}
于 2012-07-28T10:39:11.397 回答
11

那么这里的答案是你想要做的:

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

URL 不是模型本身实例的一部分,而是MyModel您从中创建模型实例的对象的属性。因此,您只需将其设置为普通的 JavaScript 对象属性即可。 set仅当您设置的数据(或相反地使用get)实际上是您要从服务器发送/接收的数据的属性时才使用。

但是为什么要更改 URL 是我们应该问的问题。Backbone 的模型/集合系统背后的想法是,您与一个 REST 端点对话,每个模型都有一个对应的端点。

就像您有一个博客并且该博客有一个“条目”对象,可在以下位置获得:

/rest/entry/

你有一个用于 Entry 的 Backbone 模型:

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

现在,当您savefetchBackbone 知道这是如何工作的时候。

所以就像你正在制作一个新模型:

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

然后,这将使 Backbone/rest/entry对正文执行 HTTP POST 请求:

{
  "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:

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

这不是你要找的,对吧?)

现在你有了这个模型,它有一个 ID。这意味着如果你改变它:

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

Backbone 现在发出 HTTP PUT 请求/rest/entry/1以更新服务器上的资源。

服务器看到您正在谈论/rest/entry/端点上的 ID 1,因此知道要更新现有记录(并发回 HTTP 200)。

TL;博士

不要更改 URL,Backbone 会。为一条新数据创建一个新模型。

于 2012-07-27T19:33:19.640 回答
4
model.urlRoot = "/your/url"

或者

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

或者

model.url = "/your/url"

或者

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

Backbone.Model 对象的默认“url”属性如下。Backbone.js 文档说:

服务器上模型表示的默认 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 具有在 urlRoot 为空的情况下回退到集合 url 的优势。

于 2012-07-30T16:55:36.337 回答
2

您可以在 fetch 函数中将 url 设置为选项,如下所示:

var mod = new MyModel();
mod.fetch({
   url: '/some/other/url',
   data: {}
});
于 2017-03-13T16:15:40.243 回答