In learning Meteor I’m trying to clone a small game (7x7, http://static.giantbomb.com/uploads/original/1/14761/2433052-7x7-screen03.png). The game is a grid of 7x7 squares, and a square has a background colour (modelled as a 7x7 array in the database with array[i][j] being the colour of row i/col j). I need to model this so that I can ‘move’ a square, by clicking on it then somewhere else - this would of course clear its background colour in its current space and change the background colour where it moves to. My first thought on how to do this was to set a data attribute on each square of the grid which I could then map back to the collection storing its state (in the database). All the detail is in that SO question, but the code for that was:
Ie, set a data attribute at render time so the squares are numbered 0-48, which I can trivially convert to a location in the 7x7 state table.
This of course doesn’t work because Meteor re-renders stuff a lot (and more generally I’m not sure I can rely on it to run this callback on cells in a table precisely in order?).
Can anyone give me any pointers on how to either preserve the data attributes when Meteor re-renders things, or on how to re-formulate my approach here which is maybe just plain wrong?
Thanks for replying! That seems reasonable but I’m a bit unsure how to map it to what I’m doing. All I’m storing is the style colours, just because storing these IDs seemed pointless (and I like the 7x7 array in the DB). So I’m binding to {{this}} which is at that point just an entry in the array (I’m just using it to build up a class name for the style).
Would you suggest using a different data structure where I store these IDs in the database is the right approach here?
Obviously it’s not much data and doesn’t really matter, it just does feel like a bit of a messy solution to store those IDs (which will always be the same 0-48/1-49 or whatever) in the database for each game.
In my event code below, if I don’t have the button.text() call, the button text is not updated. I was thinking if I just updated the selectedCmdTxt variable Meteor would take care of updating the button text for me.
'click #mt-command-dd .dropdown-menu li a': function (e, t) {
var button = $('#mt-command-dd > button');
var eventTarg = event.target;
var eventText = eventTarg.text;
selectedCmdText = eventText;
button.text(selectedCmdText);
},
What does your helper for {{selectedCommandText}} look like? For example:
Template.yourTemplate.helpers({
selectedCmdText: function(){
//what do you have here?
}
})
In your code, you’re changing the text attribute using jQuery in non-reactive way. Template helpers are reactive. Changing attributes with jQuery in an event handler is by default not reactive.
To maintain the architecture you have, you could have the event update the value of a reactive var (using the reactive-var package) or even a Session variable (though you’ll get different opinions on this) and your helper could simply return the value of the reactive var or Session variable.
I think @nkrisc has identified the underlying issue in that you need to be using a reactive data construct and use a helper to return the value of that.
There is another issue in your code: you have referenced event.target in your code, but the event object you have declared is e: function(e, t)
I have no idea what selectedCmdText references but unless it’s a reactive data source the helper will only display its initial value and will not rerun by default.
Is a global variable not a reactive data construct? I do declare the variable, and I do have a helper that returns its value (shown above).
Regarding e vs event, That’s a good point, but when I step through the code, both e and event work and the selected text is correctly retrieved by the eventText = eventTarg.text line, which seems pretty strange. Perhaps meteor automatically declares a global ‘event’ variable when inside a Template.xxx.events construct?
Thanks, that works, although it does seem a bit like we’re using a Session variable for its side effect (reactivity) rather than what Session variables are meant for.
One last related question, when I was trying to manipulate the DOM, I was successful in changing the text of the button with the button.text() function, but I never could figure out how to set the value of one of the buttons attributes. Is there a way to do that in the event handler?