【问题标题】:Meteor collection Update not properly updating on client流星收集更新未在客户端正确更新
【发布时间】:2015-04-20 08:41:48
【问题描述】:

我正在尝试更新文档。具体来说,我正在更改项目的顺序 - 对象数组。该数组称为“资源”。我调用一个方法来更新资源数组中每个对象的位置。从数据库中可以看出,文档已按正确的顺序更新。

更新时,正如预期的那样,客户端会做出反应 - 并使用新数据进行更新 - 但是,它似乎以错误的顺序显示数组......就像它的“一出”......(所以项目移动到索引 2 出现在索引 1...移动到索引 3 的项目出现在索引 2 等)但是当我对浏览器进行物理刷新时 - 数据按预期加载。有人在这里有类似(但不相同)的问题 - Meteor collection insert not updating on client - 尽管没有一个答案对我的问题有帮助。

在我的 router.js 文件中(我使用的是 ironrouter)

Router.configure({
  layoutTemplate: 'layout',
  loadingTemplate: 'loading',
  notFoundTemplate: 'notFound',
  waitOn: function() {
   return [ Meteor.subscribe('playlists'), Meteor.subscribe('resources') ];
  }
});

.....

Router.route('/playlist/:_id', {
  name: 'playlistPage',
  data: function() { 
    return Playlists.findOne(this.params._id); 
  }
});

在我拥有的客户端上:

          ...
'click #saveOrder': function(e, template) {
     e.preventDefault();

     var currentplaylistId = (template.data._id);

     var resourcesArray = [];
     $('#playlistTableBody tr').each(function(i) {
       var $this = $(this);
       var data = {
           title: $this.data('title'),
           type: $this.data('type'),
           resourceid: $this.data('resourceId'),
           duration: $this.data('duration'),
           order:  i
           }
           resourcesArray.push(data);
      });




Meteor.call('playlistUpdateResourceOrder', 
currentplaylistId, resourcesArray, function(error, result) {
    // display the error to the user and abort
     if (error)
     return throwError(error.reason);
     // Refresh data?
     Router.go('playlistPage', {_id: result._id});
});

和服务器

  playlistUpdateResourceOrder: function (currentplaylistId, resourcesArray) {
    Playlists.update(currentplaylistId, {
      $set: { resources: resourcesArray }
    });
    return {
      _id: currentplaylistId // return to our updated / renamed playlist
    };

  }

我的模板很简单:

   <tbody id="playlistTableBody">
  {{#each resources }}
    {{>resourceItem}}
  {{/each}}
</tbody>

<template name="resourceItem">
<tr data-title="{{title}}" data-type="{{type}}" data-resourceid="{{resourceId}}" data-duration="{{duration}}">
<td>{{title}}</td>
<td>{{type}}</td>
</tr>
</template>

【问题讨论】:

    标签: javascript meteor


    【解决方案1】:

    始终在客户端对数据进行排序。因为如果你在 Meteor.publish 中对数据进行排序,它只会在初始加载时对数据进行排序。

    显示已排序资源的模板如下所示:

    <template name="yourTemplate">
      {{#each resources}}
        {{>resourceItem}}
      {{/each}}
    </template>
    

    而您的助手称为 "resources",它返回已排序的资源:

    Template.yourTemplate.helpers({
      resources: function() {
        return Resources.find({}, { sort: { order: 1 } });
      }
    });
    

    您可以在助手或路由器中返回您的数据。重要的部分是:

    //Always sort collection on the client
    Resources.find({}, { sort: { order: 1 } });
    

    编辑:要对子文档进行排序,您可以使用下划线函数sortBy。下划线默认在 Meteor 应用中:

    var subDoc = [{ title: 'asdf', order: 2 }, { title: 'ah', order: 1 }];
    //Sorting by order
    var sorted = _.sortBy(subDoc, function(item) { 
      return item.order 
    });
    

    【讨论】:

    • 感谢 Thomas - 但是,这是一个子集合(对象数组),而不是集合本身。我有一个文档,其中包含一个名为资源的数组,其中包含对象。它是我要更新的资源数组。
    • 那么 Meteor.subscribe('resources') 是什么?对于排序子文档,您可以使用下划线 sortBy 函数:underscorejs.org/#sortBy
    • resources collection 是另外一回事 - 抱歉,我应该注释掉那一行。我没有得到的是 - 在我的 tbody 中,资源数组以错误的顺序写出。然而,如果我将相同的代码放在页面上,在 tbody 之外......它会以正确的顺序呈现。它必须与插件有关(影响 tbody)。我删除了插件并尝试在 Chrome 调试中手动操作 dom(从顶部剪切第一个 TR,并粘贴在底部)。然后我点击保存 - 并遇到了同样的问题......所以似乎每当 dom 被 jquery 或 bruce force 手动操作时?
    • 你可能做错了什么。从 HTML 到 JavaScript 获取数据并不好。您已经在 J​​avaScript 中渲染了数据,为什么不使用它们呢?我没有在您的代码中看到您获得“资源”的位置,但我可以看到您正试图通过 jQuery 从 HTML 中获取它们。这不好。您应该以与在模板中传递它们相同的方式获取它们。
    • 我使用 javascript 来提供可排序的功能 - 然后捕获新的排序顺序,并写回子文档。与几个人交谈后,似乎流星对子文档的效果不太好,所以我需要将每个资源都移到自己的集合中。
    猜你喜欢
    • 2015-02-06
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 2015-01-20
    • 2013-05-23
    • 2018-06-17
    相关资源
    最近更新 更多