使用 Meteor 和 blaze 在 handsontable 上正确加载数据
Loading data correctly on handsontable with Meteor and blaze
我通过插件在 Meteor 1.4.1 上使用 handsontable awsp:handsontable@0.16.1
我遇到的问题是每次更改值时都会重新呈现矩阵,这会产生两个问题。第一个是编辑单元格的焦点丢失,滚动回到顶部。第二个是有时值不会保存,因为每次更改都会重新加载矩阵的数据。
我订阅数据并呈现 table 的方式如下:
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);
}
});
});
我想要实现的是只创建一次矩阵,而不是在每次数据更改时重新创建它,这样焦点就会保留并且数据始终得到保存。
因此,我尝试按照此 question
中的建议,仅在 this.autorun() 块内保留最后两行
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);
}
});
});
但是我第一次加载页面时,数据不可用,所以我收到错误
Cannot read property 'turn' of undefined
因此,如何在单元格值更改时正确获取创建 table 所需的所有数据而不重新渲染它?
在此先感谢您的帮助。
您正在尝试在 Scenarios 和 ConnectivityMatrix 集合准备就绪之前对其进行查询。将所有 mongo 查询移动到 this.subscriptionsReady()
条件块中。
我设法完成我需要的方法是在渲染矩阵后停止计算。代码如下:
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();
}
});
});
我通过插件在 Meteor 1.4.1 上使用 handsontable awsp:handsontable@0.16.1
我遇到的问题是每次更改值时都会重新呈现矩阵,这会产生两个问题。第一个是编辑单元格的焦点丢失,滚动回到顶部。第二个是有时值不会保存,因为每次更改都会重新加载矩阵的数据。
我订阅数据并呈现 table 的方式如下:
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);
}
});
});
我想要实现的是只创建一次矩阵,而不是在每次数据更改时重新创建它,这样焦点就会保留并且数据始终得到保存。 因此,我尝试按照此 question
中的建议,仅在 this.autorun() 块内保留最后两行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);
}
});
});
但是我第一次加载页面时,数据不可用,所以我收到错误
Cannot read property 'turn' of undefined
因此,如何在单元格值更改时正确获取创建 table 所需的所有数据而不重新渲染它?
在此先感谢您的帮助。
您正在尝试在 Scenarios 和 ConnectivityMatrix 集合准备就绪之前对其进行查询。将所有 mongo 查询移动到 this.subscriptionsReady()
条件块中。
我设法完成我需要的方法是在渲染矩阵后停止计算。代码如下:
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();
}
});
});