javascript 是否可以使用对象 ID 而不是对象来初始化主干集合?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6931257/
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-10-25 22:22:59  来源:igfitidea点击:

Is it possible to initialise a backbone Collection with object IDs rather than objects?

javascriptbackbone.jsbackbone.js-collections

提问by Joe

I have a Backbone.js Collection and I have an array of model IDs that I want to populate it. I know that I could fetch these objects one by one, build an array of objects and pass them into the Collection's constructor as an array.

我有一个 Backbone.js 集合,我有一个模型 ID 数组,我想填充它。我知道我可以一个一个地获取这些对象,构建一个对象数组并将它们作为数组传递给 Collection 的构造函数。

What I'd like to be able to do is pass the array of object ids into the constructor as initial data, and get the Collection to fetch them, possibly as batch, as per this.

我希望能够做的是将对象 id 数组作为初始数据传递到构造函数中,并让 Collection 获取它们,可能是批处理,根据this

Doable?

可行吗?

回答by satchmorun

When you call 'fetch' on a Backbone.Collection, it in turn calls Backbone.sync, which by default just asks the collection for the url to use.

当您在 Backbone.Collection 上调用 'fetch' 时,它会依次调用 Backbone.sync,默认情况下它只要求集合提供要使用的 url。

So if your server responds to:

因此,如果您的服务器响应:

/models/batch/?ids=1,2,3,4

You could do something like:

你可以这样做:

var MyCollection = Backbone.Collection.extend({

    model: Model,

    url: '/models',

    initialize: function(models, options) {
        ids = options.ids || [];
        if (ids.length > 0) { 
            this.fetchByIds(ids);
        }
    },

    fetchByIds: function(ids) {
        // Save a reference to the existing url
        var baseUrl = this.url;

        // Assign our batch url to the 'url' property and call the server
        this.url += '/?ids=' + ids.join(',');
        this.fetch();

        // Restore the 'url' property
        this.url = baseUrl;
    }
});

And use it like so:

并像这样使用它:

var coll = new MyCollection({}, {ids: [1, 2, 3, 4]});

You'd have to pass the ids in the options parameter, because the Backbone.Collection constructor function sets the models passed in the first parameter before it calls the 'initialize' function.

您必须在 options 参数中传递 id,因为 Backbone.Collection 构造函数在调用 'initialize' 函数之前设置在第一个参数中传递的模型。

Theoretically, this should work (read: completely untried).

从理论上讲,这应该有效(阅读:完全未尝试过)。

回答by Scott Stafford

On initial page load, you shouldn't use fetch -- it should be bootstrapped as using resetdescribed here: http://documentcloud.github.com/backbone/#FAQ-bootstrap.

在初始页面加载时,您不应该使用 fetch - 它应该按照reset此处描述的方式进行引导:http: //documentcloud.github.com/backbone/#FAQ-bootstrap

From the link:

从链接:

Loading Bootstrapped Models

加载自举模型

When your app first loads, it's common to have a set of initial models that you know you're going to need, in order to render the page. Instead of firing an extra AJAX request to fetch them, a nicer pattern is to have their data already bootstrapped into the page. You can then use reset to populate your collections with the initial data. At DocumentCloud, in the ERB template for the workspace, we do something along these lines:

当您的应用程序首次加载时,通常会有一组您知道将需要的初始模型,以便呈现页面。与其触发额外的 AJAX 请求来获取它们,更好的模式是让它们的数据已经引导到页面中。然后,您可以使用 reset 用初始数据填充您的集合。在 DocumentCloud,在工作区的 ERB 模板中,我们执行以下操作:

<script>
  Accounts.reset(<%= @accounts.to_json %>);
  Projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>

回答by Craig Monson

You can actually set url to a function too. I'd just override fetch instead of fetchByIds: Also, I think that baseUrl is for the Model only, not the Collection. I think rulfzid has the right idea, but I think I'd do it like so:

您实际上也可以将 url 设置为函数。我只是覆盖 fetch 而不是 fetchByIds:另外,我认为 baseUrl 仅适用于模型,而不适用于集合。我认为 rulfzid 的想法是正确的,但我想我会这样做:

var MyCollection = Backbone.Collection.extend({
  model: Model,

  initialize: function(models, opts) {
    if (options.ids) {
      this.fetch(options.ids);
    }  
  },

  url: function() {
    var url = '';
    if (this.fetch_ids) {
      // pass ids as you would a multi-select so the server will parse them into
      // a list for you.  if it's rails you'd do: id[]=
      url = '/models?id=' + ids.join('&id=');
      // clear out send_ids
      this.fetch_ids = undefined;
    } else {
      url = '/models';
    }
    return url;
  },

  fetch: function(args) {
    if (args.ids) {
      this.fetch_ids = args.ids;
    }
    return Backbone.Model.prototype.fetch.call(this, args);
  }
});

I think it keeps the functionality in the proper 'place', and it allows more reusability (ie, you can fetch(list_of_ids) any time... you don't need a new object)

我认为它将功能保留在适当的“位置”,并且允许更多的可重用性(即,您可以随时获取(list_of_ids)...您不需要新对象)