mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
fix race condition on list cleanup
This commit is contained in:
@@ -865,8 +865,10 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
|
||||
}
|
||||
}
|
||||
initialContents = null; // save memory
|
||||
var stopped = false;
|
||||
var cleanup = function () {
|
||||
handle.stop();
|
||||
stopped = true;
|
||||
};
|
||||
html = annotate(html, Spark._ANNOTATION_LIST, function (range) {
|
||||
outerRange = range;
|
||||
@@ -894,10 +896,17 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
|
||||
walk.rendered.call(walk.landmark);
|
||||
};
|
||||
|
||||
var later = function (f) {
|
||||
atFlushTime(function () {
|
||||
if (! stopped)
|
||||
f();
|
||||
});
|
||||
};
|
||||
|
||||
// The DOM update callbacks.
|
||||
_.extend(callbacks, {
|
||||
added: function (item, beforeIndex) {
|
||||
atFlushTime(function () {
|
||||
later(function () {
|
||||
var frag = Spark.render(_.bind(itemFunc, null, item));
|
||||
DomUtils.wrapFragmentForContainer(frag, outerRange.containerNode());
|
||||
var range = new LiveRange(Spark._TAG, frag);
|
||||
@@ -915,7 +924,7 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
|
||||
},
|
||||
|
||||
removed: function (item, atIndex) {
|
||||
atFlushTime(function () {
|
||||
later(function () {
|
||||
if (itemRanges.length === 1) {
|
||||
var frag = Spark.render(elseFunc);
|
||||
DomUtils.wrapFragmentForContainer(frag, outerRange.containerNode());
|
||||
@@ -930,7 +939,7 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
|
||||
},
|
||||
|
||||
moved: function (item, oldIndex, newIndex) {
|
||||
atFlushTime(function () {
|
||||
later(function () {
|
||||
if (oldIndex === newIndex)
|
||||
return;
|
||||
|
||||
@@ -948,7 +957,7 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
|
||||
},
|
||||
|
||||
changed: function (item, atIndex) {
|
||||
atFlushTime(function () {
|
||||
later(function () {
|
||||
Spark.renderToRange(itemRanges[atIndex], _.bind(itemFunc, null, item));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3526,3 +3526,50 @@ Tinytest.add("spark - unique label", function (test) {
|
||||
test.equal(bufstr(), 'ddd');
|
||||
|
||||
});
|
||||
|
||||
Tinytest.add("spark - list update", function (test) {
|
||||
var R = ReactiveVar('foo');
|
||||
|
||||
var lst = [];
|
||||
lst.callbacks = [];
|
||||
lst.observe = function(callbacks) {
|
||||
lst.callbacks.push(callbacks);
|
||||
_.each(lst, function(x, i) {
|
||||
callbacks.added(x, i);
|
||||
});
|
||||
return {
|
||||
stop: function() {
|
||||
lst.callbacks = _.without(lst.callbacks, callbacks);
|
||||
}
|
||||
};
|
||||
};
|
||||
lst.another = function () {
|
||||
var i = lst.length;
|
||||
lst.push({_id:'item'+i});
|
||||
_.each(lst.callbacks, function (callbacks) {
|
||||
callbacks.added(lst[i], i);
|
||||
});
|
||||
};
|
||||
var div = OnscreenDiv(Meteor.render(function() {
|
||||
return R.get() + Spark.list(lst, function () {
|
||||
return '<hr>';
|
||||
});
|
||||
}));
|
||||
|
||||
lst.another();
|
||||
Meteor.flush();
|
||||
test.equal(div.html(), "foo<hr>");
|
||||
|
||||
lst.another();
|
||||
R.set('bar');
|
||||
Meteor.flush();
|
||||
test.equal(div.html(), "bar<hr><hr>");
|
||||
|
||||
R.set('baz');
|
||||
lst.another();
|
||||
Meteor.flush();
|
||||
test.equal(div.html(), "baz<hr><hr><hr>");
|
||||
|
||||
div.kill();
|
||||
Meteor.flush();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user