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

发布于 2024-11-27 15:33:29 字数 260 浏览 0 评论 0原文

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

我想要做的是将对象 id 数组作为初始数据传递到构造函数中,并让 Collection 来获取它们,可能作为批处理,按照 这个

可行吗?

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.

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.

Doable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

灵芸 2024-12-04 15:33:29

当您在 Backbone.Collection 上调用“fetch”时,它会依次调用 Backbone.sync,默认情况下,它仅向集合询问要使用的 url。

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

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

您可以这样做:

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

并像这样使用它:

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

您必须在选项参数中传递 ids,因为 Backbone.Collection 构造函数在调用之前设置在第一个参数中传递的模型“初始化”功能。

从理论上讲,这应该可行(阅读:完全未经尝试)。

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.

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.

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

这个俗人 2024-12-04 15:33:29

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

来自链接:

加载引导模型

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

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

On initial page load, you shouldn't use fetch -- it should be bootstrapped as using reset described here: 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:

<script>
  Accounts.reset(<%= @accounts.to_json %>);
  Projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>
烏雲後面有陽光 2024-12-04 15:33:29

实际上,您也可以将 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);
  }
});

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

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:

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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文