问题
I have a nested template, using a ReactiveDict to store the data, which is an object that includes variables (color, type...) and an array of children nodes.
I'm having an issue on refresh: the array displays reactively, but when I update the array, it does not properly render.
in short (cleaned up code):
<body>
{{#with data}}
{{>nested}}
{{/with}}
</body>
<template name="nested">
<div>{{color}}<div>
<div class="ui dropdown">
<!-- drop down stuff goes here-->
</div>
{{#if children}}
{{#each children}}
{{>nested scope=this}}
{{/each}}
{{/if}}
</template>
Template.body.helpers({
"data": { color: "blue",
children: [{color: "green", children: [{color: "teal"}]},
{color:"red", children:[{color: "cyan"}],{color: "magenta"}]]}}
})
Template.nested.onCreated(function(){
this.scope = new ReactiveDict();
this.scope.set('scope', this.data.scope);
})
Template.nested.helpers({
"color": function () { Template.instance().scope.get('scope').color;},
"children": function () {
return Template.instance().scope.get('scope').children;
}
})
Template.nested.events({
"click .ui.dropdown > .menu > .item": function(e, t) {
e.preventDefault();
e.stopPropagation();
var data = t.scope.get('scope');
//do processing stuff here...
updatedArray = myFunction();
data['children'] = updatedArray;
t.scope.set('scope', data);
}
})
So what's happening is that on update the elements alreayd present do not update, and if there are elements added they show up. if there are elements removed, they elements will be removed but the data in the variables (color here) does not get updated.
To make it work so far, I had to do the following:
Template.nested.events({
"click .ui.dropdown > .menu > .item": function(e, t) {
e.preventDefault();
e.stopPropagation();
var data = t.scope.get('scope');
//do processing stuff here...
updatedArray = myFunction();
delete data.children;
t.scope.set('scope', data);
Meteor.setTimeout(function() {
data['children'] = updatedArray;
t.scope.set('scope', data);
},10);
}
})
That works but it's a total hack forcing the array to nothing and then refreshing after a short timeout.
How am I supposed to do this the proper way?
PS: I tried using allDeps.changed()
on the ReactiveDict
, and i tried forcing a re-render but it's in the render loop so it won't render the view twice.
Can't seem to understand why the array elements are not updated. I know when using collections MiniMongo checks for _id's of the objects to see if they changed or not, but there are no _id in my objects. I also tried to add one but without much luck
回答1:
well I guess I asked just before figuring it out... the '_id' thing did the trick. I had tried before but I was actually using the same _id for the same elements so they did not appear to change (duh!)
So by adding a { "_id": Meteor.uuid() }
in my generated objects, the update works fine.
来源:https://stackoverflow.com/questions/35472921/meteor-reactive-array-rendering-issues-on-update