Javascript Backbone.js 更改模型的 url 参数并获取不更新获取的数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11694425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:45:22  来源:igfitidea点击:

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

javascriptbackbone.js

提问by Vikram

I have the following Model:

我有以下型号:

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'});

I use this global variable 'mod' to fetch some data into this model from backend.

我使用这个全局变量“mod”从后端获取一些数据到这个模型中。

 // fetch

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

 });

All above works well.... My Issue: I want to reuse this model by changing resetting the url and call fetch but it does not update the url somehow. I have tried the following:

以上所有工作都很好.... 我的问题:我想通过更改重置 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

How do I set the url for my model so that I could call fetch() and it fetches data from updated url? Am I missing something. Thanks for any pointers..

如何为我的模型设置 url,以便我可以调用 fetch() 并从更新的 url 中获取数据?我是不是错过了什么。感谢您的任何指点..

UPDATE 1: Basically, I am unable to get updated values if I did

更新 1:基本上,如果我这样做了,我将无法获得更新的值

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

followed by

其次是

    model.fetch();

'model' is a global variable. Creating a fresh instance of 'model' works:

'model' 是一个全局变量。创建一个新的“模型”实例工作:

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

however, works as required. Does this mean that a model instance is permanently attached to a url and it cannot be reset?

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

ANSWER TO MY QUESTION in UPDATE 1Model instance is not permanently attached to a url. It can be reset dynamically. Please read through @tkone's thorough explanation and then @fguillens' solution for a better understanding.

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

回答by fguillen

After have understood the @tkone 's explanation...

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

If you still want to have a dynamic Model.urlyou always can delay its construction to run time, try this:

如果你仍然想要一个动态Model.url你总是可以延迟它的构建到运行时间,试试这个:

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

回答by tkone

Well the answer here is that you want to do:

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

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

The URL isn't part of the instance of the model itself, but rather an attribute of the MyModelobject that you're creating your model instance from. Therefore, you'd just set it like it was an normal JavaScript object property. setis used only when the data you're setting (or conversely getting with get) is actually an attribute of the data you want to send/receive from the server.

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

But why you're changing the URL is the question we should be asking. The idea behind Backbone's model/collection system is that you speak to a REST endpoint and each model has a corresponding endpoint.

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

Like you've got a blog and that blog has an "entry" object which is available at:

就像您有一个博客并且该博客有一个“条目”对象,该对象位于:

/rest/entry/

And you've got a Backbone model for Entry:

你有一个 Entry 的 Backbone 模型:

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

Now when you saveor fetchBackbone knows how this works.

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

So like you're making a new model:

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

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

This would then make Backbone do an HTTP POST request to /rest/entrywith the body:

这将使 Backbone/rest/entry对主体执行 HTTP POST 请求:

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

(When you do your mod.set({url: '/some/other/url'});you're actually adding a field called urlto the dataset, so the server would send "url": "/some/other/url"as part of that JSON POST body above:

(当您这样做时,您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" 
}

The server would then respond with an HTTP 200 (or 201) response with the same model, only with, like, say, and ID attached:

然后,服务器将使用相同模型的 HTTP 200(或 201)响应进行响应,仅附加诸如 ID 之类的信息:

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

And that's not what you're looking for, right?)

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

Now you've got this model and it's got an ID. This means if you change it:

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

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

Backbone now makes an HTTP PUT request on /rest/entry/1to update the resource on the server.

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

The server sees that you're talking about ID 1 on the /rest/entry/endpoint, so knows to update an existing record (and send back an HTTP 200).

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

TL;DR

TL; 博士

Don't change the URL, Backbone will. Make a new model for a new piece of data.

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

回答by Venkat Kotra

model.urlRoot = "/your/url"

OR

或者

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

OR

或者

model.url = "/your/url"

OR

或者

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

Default 'url' property of a Backbone.Model object is as below. Backbone.js doc says:

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

Default URL for the model's representation on the server -- if you're using Backbone's restful methods, override this to change the endpoint that will be called.

服务器上模型表示的默认 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);
},

Clearly, It first gets the value of urlRoot, if not available, it will look at the url of the collection to which model belongs. By defining urlRoot instead of url has an advantage of falling back to collection url in case urlRoot is null.

显然,它首先获取 urlRoot 的值,如果不可用,它会查看模型所属的集合的 url。通过定义 urlRoot 而不是 url 具有回退到集合 url 的优势,以防 urlRoot 为空。

回答by Yuriy Korman

You can set url as option in fetch function, like this:

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

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