简体   繁体   中英

Meteor collection Update not properly updating on client

I'm trying to update a document. Specifically, I'm changing the order of items - an array of objects. The array is called 'resources'. I call a method to update the position of each object within the resources array. I can see from looking in the database that the document has been updated with the correct order.

On update, as expected, the client reacts - and updates with the new data - however, it appears to be displaying the array in the wrong order... its like its 'one out'... (so the item moved to index 2 appears at index 1... the item moved to index 3 appears at index 2 etc) yet when I do a physical refresh of the browser - the data loads as expected. Someone has a similar (but not identical) issue here - Meteor collection insert not updating on client - although none of the answers have helped with my problem.

In my router.js file (I'm using 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); 
  }
});

On the client I have:

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

and server

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

  }

My templates are very simple:

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

and

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

Always sort data on the client. Because if you sort data in Meteor.publish, it will sort the data only on initial load.

Your template for showing sorted resources can look like this:

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

And your helper called "resources" that returns sorted resources:

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

You can return your data in helper or router. Important part is:

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

EDIT: To sort subdocument, you can use Underscore function sortBy . Underscore is in Meteor app by default:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM