主干.js更改模型的 url 参数,提取不会更新获取的数据

backbone.js change url parameter of a Model and fetch does not update data fetched

本文关键字:提取 更新 数据 获取 参数 js 模型 url 主干      更新时间:2024-05-04

>我有以下模型:

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的解决方案以更好地理解。

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

如果您仍然想要一个动态Model.url并且始终可以将其构造延迟到运行时,请尝试以下操作:

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

这里的答案是你想做:

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

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

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

就像你有一个博客,

这个博客有一个"入口"对象,可以在以下位置找到:

/rest/entry/

你有一个用于入口的主干模型:

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

现在,当您savefetch Backbone知道这是如何工作的。

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

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:

{
  "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 现在在/rest/entry/1上发出 HTTP PUT 请求以更新服务器上的资源。

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

博士

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

model.urlRoot = "/your/url"

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

model.url = "/your/url"

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

Backbone.Model 对象的默认"url"属性如下所示。骨干.js医生 说:

模型在服务器上表示形式的默认 URL - 如果您使用的是 Backbone 的 restful 方法,请覆盖此 URL 以更改将调用的终结点。

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 为 null 的情况下回退到集合 url。

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

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