使用Meteor和fireze正确加载数据

时间:2016-08-26 16:54:40

标签: javascript meteor meteor-blaze handsontable

我在Meteor 1.4.1上通过插件使用handontable awsp:handsontable@0.16.1

我遇到的问题是每次更改值时都会重新呈现矩阵,这会产生两个问题。第一个是编辑单元格的焦点丢失,滚动返回顶部。第二个问题是有时候不会保存这些值,因为每次更改都会重新加载矩阵的数据。

我订阅数据和呈现表格的方式如下:

Template.connectivityMatrix.onCreated(function () {
  this.activeScenario = () => Session.get('active_scenario');

  this.autorun(() => {
    this.subscribe('connectivityMatrixUser', this.activeScenario());
  });
});

Template.connectivityMatrix.onRendered(function () {
  this.autorun(() => {
    if (this.subscriptionsReady()) {
      const activeScenario = Session.get('active_scenario');
      const currentScenario = Scenarios.findOne({_id: activeScenario});
      const currentTurn = currentScenario.turn;
      const numObj = ConnectivityMatrix.find({scenario_id: activeScenario, user_id: Meteor.userId(), turn: currentTurn}).count();

      var myData = [];  // Need this to create instance
      var container = document.getElementById('connectivity-matrix');

      var hot = new Handsontable(container, { // Create Handsontable instance
        data: myData,
        startRows: numObj,
        startCols: numObj,
        afterChange: function (change, source) {  // 'change' is an array of arrays.
          if (source !== 'loadData') {  // Don't need to run this when data is loaded
            for (i = 0; i < change.length; i++) {   // For each change, get the change info and update the record
              var rowNum = change[i][0]; // Which row it appears on Handsontable
              var row = myData[rowNum];  // Now we have the whole row of data, including _id
              var key = change[i][1];  // Handsontable docs calls this 'prop'
              var oldVal = change[i][2];
              var newVal = change[i][3];
              var setModifier = {$set: {}};   // Need to build $set object
              setModifier.$set[key] = newVal; // So that we can assign 'key' dynamically using bracket notation of JavaScript object
              ConnectivityMatrix.update(row._id, setModifier);
            }
          }
        }
      });

      myData = ConnectivityMatrix.find({scenario_id: activeScenario, turn: currentTurn, user_id: Meteor.userId()}, {sort: {created_at: 1}}).fetch();  // Tie in our data
      hot.loadData(myData);
    }
  });
});

我想要实现的只是创建矩阵一次,而不是在每次数据更改时重新创建矩阵,以便保持焦点并始终保存数据。 所以我试图只留下this.autorun()块内的最后两行,如question

所示
Template.connectivityMatrix.onRendered(function () {
  const activeScenario = Session.get('active_scenario');
  const currentScenario = Scenarios.findOne({_id: activeScenario});
  const currentTurn = currentScenario.turn;
  const numObj = ConnectivityMatrix.find({scenario_id: activeScenario, user_id: Meteor.userId(), turn: currentTurn}).count();

  var hot = new Handsontable(container, { // Create Handsontable instance
    ...
  });

  this.autorun(() => {
    if (this.subscriptionsReady()) {
      myData = ConnectivityMatrix.find({scenario_id: activeScenario, turn: currentTurn, user_id: Meteor.userId()}, {sort: {created_at: 1}}).fetch();  // Tie in our data
      hot.loadData(myData);
    }
  });
});

但是第一次加载页面时,数据不可用,所以我收到了错误

  

无法读取未定义的属性'turn'

因此,如何在单元格值更改时正确获取创建表所需的所有数据而不重新呈现它?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您正准备在方案和ConnectivityMatrix集合准备好之前查询它们。在this.subscriptionsReady()条件块中移动所有mongo查询。

答案 1 :(得分:0)

我设法做我需要的方法是在渲染矩阵后停止计算。代码如下:

Template.connectivityMatrix.onRendered(function () {    
  this.autorun((computation) => {
    if (this.subscriptionsReady()) {    
      const currentScenario = Scenarios.findOne({_id: activeScenario});
      const currentTurn = currentScenario.turn;
      const numObj = ConnectivityMatrix.find({scenario_id: activeScenario, user_id: Meteor.userId(), turn: currentTurn}).count();

      var myData = [];  // Need this to create instance
      var container = document.getElementById('connectivity-matrix');

      var hot = new Handsontable(container, { // Create Handsontable instance
        data: myData,
        colHeaders: arrayRowsCols,
        rowHeaders: arrayRowsCols,
        height: '450',
        maxRows: numObj,
        maxCols: numObj,
        columns: columns,
        afterChange: function (change, source) {  // 'change' is an array of arrays.
          if (source !== 'loadData') {  // Don't need to run this when data is loaded
            for (i = 0; i < change.length; i++) {   // For each change, get the change info and update the record
              var rowNum = change[i][0]; // Which row it appears on Handsontable
              var row = myData[rowNum];  // Now we have the whole row of data, including _id
              var key = change[i][1];  // Handsontable docs calls this 'prop'
              var oldVal = change[i][2];
              var newVal = change[i][3];
              var setModifier = {$set: {}};   // Need to build $set object
              setModifier.$set[key] = newVal; // So that we can assign 'key' dynamically using bracket notation of JavaScript object
              ConnectivityMatrix.update(row._id, setModifier);
            }
          }
        }
      });

      myData = ConnectivityMatrix.find({scenario_id: activeScenario, turn: currentTurn, user_id: Meteor.userId()}, {sort: {created_at: 1}}).fetch();  // Tie in our data
      hot.loadData(myData);
      computation.stop();
    }
  });
});