Skip to content

Commit 1fbbb8d

Browse files
committed
Fixes for nested each/option queries.
Now the _template of an VirtualElement will be cloned to it's state to prevent changes to it from actions performt in an other iteration. Also every state on elements with an option query will now contain a seperated footers and headers array for the same reason as the template. Closes #126
1 parent f9ce47c commit 1fbbb8d

File tree

2 files changed

+51
-22
lines changed

2 files changed

+51
-22
lines changed

src/query/VirtualElement.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ define([
356356
attributes: {},
357357
style: {},
358358
html: null,
359-
expressions: {}
359+
expressions: {},
360+
template: blocks.clone(this._template || this._children)
360361
};
361362
if (!this._states) {
362363
this._states = {};
@@ -395,7 +396,7 @@ define([
395396

396397
renderChildren: function (domQuery, syncIndex) {
397398
var html = '';
398-
var children = this._template || this._children;
399+
var children = this._state && this._state.template || this._template || this._children;
399400
var length = children.length;
400401
var index = -1;
401402
var child;
@@ -453,7 +454,7 @@ define([
453454
},
454455

455456
syncChildren: function (domQuery, syncIndex, offset) {
456-
var children = this._template || this._children;
457+
var children = this._state && this._state.template || this._template || this._children;
457458
var length = children.length;
458459
var state = this._state;
459460
var element = this._el.nodeType == 8 ? this._el : this._el.childNodes[offset || 0];
@@ -513,13 +514,14 @@ define([
513514
},
514515

515516
updateChildren: function (collection, updateCount, domQuery, domElement) {
516-
var template = this._template;
517+
var template = this._state && this._state.template || this._template;
517518
var child = template[0];
518519
var isOneChild = template.length === 1 && VirtualElement.Is(child);
519520
var childNodes = domElement.childNodes;
520521
var syncIndex = domQuery.getSyncIndex();
521522
var chunkLength = this._length();
522-
var offset = this._headers ? this._headers.length : 0;
523+
var headers = this._state && this._state.headers || this._headers;
524+
var offset = headers ? headers.length : 0;
523525
var index = -1;
524526

525527
while (++index < updateCount) {
@@ -538,10 +540,13 @@ define([
538540

539541
clone: function () {
540542
var element = this._el;
543+
var parent = this._parent;
544+
this._parent = null;
541545
this._el = null;
542546
this.clone = null;
543547
var clone = blocks.clone(this, true);
544548
clone.clone = this.clone = VirtualElement.prototype.clone;
549+
clone._parent = this._parent = parent;
545550
this._el = element;
546551
return clone;
547552
},
@@ -669,7 +674,15 @@ define([
669674
}
670675
});
671676
},
672-
677+
_setChildren: function (children) {
678+
this._children = children;
679+
if (this._template || this._each) {
680+
this._template = blocks.clone(children, true);
681+
}
682+
if (this._state) {
683+
this._state.template = blocks.clone(children, true);
684+
}
685+
},
673686
_executeAttributeExpressions: function (context) {
674687
var isVirtual = this._el ? false : true;
675688
var attributes = this._state && this._state.attributes;

src/query/queries.js

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ define([
9898
var templateName = template.parameterName;
9999
template = template.rawValue;
100100
if (value) {
101-
value = value.rawValue;
101+
value = value.rawValue;
102102
}
103103

104104
template = blocks.$unwrap(template);
@@ -120,7 +120,8 @@ define([
120120
if (!this._el) {
121121
var element = document.createElement('div');
122122
element.innerHTML = html;
123-
this._children = createVirtual(element.childNodes[0], this);
123+
var children = createVirtual(element.childNodes[0], this);
124+
this._setChildren(children);
124125
this._innerHTML = null;
125126
} else {
126127
this.html(html);
@@ -264,9 +265,9 @@ define([
264265
supportsComments: true,
265266

266267
_getStaticHtml: function (domQuery, element) {
267-
var children = element._children;
268-
var headers = element._headers;
269-
var footers = element._footers;
268+
var children = element._state && element._state.template || element._template || element._children;
269+
var headers = element._state && element._state.headers || element._headers;
270+
var footers = element._state && element._state.footer || element._footers;
270271
var index = -1;
271272
var headerHtml = '';
272273
var footerHtml = '';
@@ -286,8 +287,13 @@ define([
286287
}
287288
}
288289
} else {
289-
headers = element._headers = [];
290-
footers = element._footers = [];
290+
if (element._state) {
291+
headers = element._state.headers = [];
292+
footers = element._state.footers = [];
293+
} else {
294+
headers = element._headers = [];
295+
footers = element._footers = [];
296+
}
291297

292298
while (++index < children.length) {
293299
child = children[index];
@@ -331,14 +337,14 @@ define([
331337
var staticHtml;
332338
var html;
333339

334-
if (this._sync) {
340+
if (element._sync) {
335341
element.updateChildren(collection, collection.length, domQuery, this._el);
336342
return;
337343
}
338344

339-
this._template = this._template || this._children;
345+
element._template = element._template || element._children;
340346

341-
this._childrenEach = true;
347+
element._childrenEach = true;
342348

343349
if (domQuery._serverData) {
344350
elementData = domQuery._serverData[ElementsData.id(this)];
@@ -347,9 +353,14 @@ define([
347353
var div = document.createElement('div');
348354
div.innerHTML = elementData;
349355
element._template = element._children = createVirtual(div.childNodes[0], element);
356+
if (element._state) {
357+
element._state.template = blocks.clone(element._template, true);
358+
}
350359
}
351360
}
352361

362+
363+
353364
staticHtml = queries.each._getStaticHtml(domQuery, element);
354365
html = staticHtml.header;
355366

@@ -435,10 +446,13 @@ define([
435446
var value = Expression.Create('{{' + (options.value || $thisStr) + '}}', 'value');
436447
var caption = blocks.isString(options.caption) && new VirtualElement('option');
437448
var option = new VirtualElement('option');
438-
var children = this._children;
449+
var children = this._state && this._state.template || this._template || this._children;
439450
var i = 0;
440451
var child;
441-
452+
if (this._sync) {
453+
blocks.queries.each.preprocess.call(this, domQuery, collection);
454+
return;
455+
}
442456
for (; i < children.length; i++) {
443457
child = children[i];
444458
if (!child._attributes || (child._attributes && !child._attributes['data-role'])) {
@@ -449,22 +463,24 @@ define([
449463
option._attributeExpressions.push(value);
450464
option._children.push(text);
451465
option._parent = this;
452-
this._children.push(option);
466+
children.push(option);
453467

454468
if (caption) {
455469
caption._attributes['data-role'] = 'header';
456470
caption._innerHTML = options.caption;
457-
this.addChild(caption);
471+
caption._parent = this;
472+
children.push(caption);
458473
}
459474
blocks.queries.each.preprocess.call(this, domQuery, collection);
460475
},
461476

462477
update: function (domQuery, collection) {
463478
var elementData = ElementsData.data(this);
464479
var rawCollection = collection();
465-
var headers = elementData.virtual._headers;
480+
var state = elementData.virtual._state;
481+
var headers = state && state.headers || elementData.virtual._headers;
466482
var valueObservable = elementData.valueObservable;
467-
var valueExpression = elementData.virtual._template[0]._attributeExpressions[0];
483+
var valueExpression = (state && state.template[0] || elementData.virtual._template[0])._attributeExpressions[0];
468484
var rawValue = blocks.isObservable(valueObservable) ? valueObservable._getValue() : this.value;
469485
var expression;
470486
var value;

0 commit comments

Comments
 (0)