Skip to content

Commit 24bc4b6

Browse files
committed
fix(render): don’t store a document fragment as bound element
When a template contains bound text nodes as root nodes, we used to store the document fragment that we got from cloning `template.content`. However, this fragment will be empty as soon as the view gets attached. Now we store `null` instead of the document fragment in this case. Also groups the 3 cases in `_createView` so they are easier to understand.
1 parent 2351896 commit 24bc4b6

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

modules/angular2/src/render/dom/dom_renderer.ts

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -209,34 +209,35 @@ export class DomRenderer extends Renderer {
209209
}
210210

211211
_createView(protoView: DomProtoView, inplaceElement): DomView {
212-
var rootElementClone =
213-
isPresent(inplaceElement) ? inplaceElement : DOM.importIntoDoc(protoView.element);
212+
var rootElementClone;
214213
var elementsWithBindingsDynamic;
215-
if (protoView.isTemplateElement) {
216-
elementsWithBindingsDynamic =
217-
DOM.querySelectorAll(DOM.content(rootElementClone), NG_BINDING_CLASS_SELECTOR);
218-
} else {
219-
elementsWithBindingsDynamic = DOM.getElementsByClassName(rootElementClone, NG_BINDING_CLASS);
220-
}
221-
222-
var elementsWithBindings = ListWrapper.createFixedSize(elementsWithBindingsDynamic.length);
223-
for (var binderIdx = 0; binderIdx < elementsWithBindingsDynamic.length; ++binderIdx) {
224-
elementsWithBindings[binderIdx] = elementsWithBindingsDynamic[binderIdx];
225-
}
226-
227214
var viewRootNodes;
228-
if (protoView.isTemplateElement) {
229-
var childNode = DOM.firstChild(DOM.content(rootElementClone));
230-
viewRootNodes =
231-
[]; // TODO(perf): Should be fixed size, since we could pre-compute in in DomProtoView
215+
if (isPresent(inplaceElement)) {
216+
rootElementClone = inplaceElement;
217+
elementsWithBindingsDynamic = [];
218+
viewRootNodes = [inplaceElement];
219+
} else if (protoView.isTemplateElement) {
220+
rootElementClone = DOM.importIntoDoc(DOM.content(protoView.element));
221+
elementsWithBindingsDynamic =
222+
DOM.querySelectorAll(rootElementClone, NG_BINDING_CLASS_SELECTOR);
223+
var childNode = DOM.firstChild(rootElementClone);
224+
// TODO(perf): Should be fixed size, since we could pre-compute in in DomProtoView
225+
viewRootNodes = [];
232226
// Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
233227
while (childNode != null) {
234228
ListWrapper.push(viewRootNodes, childNode);
235229
childNode = DOM.nextSibling(childNode);
236230
}
237231
} else {
232+
rootElementClone = DOM.importIntoDoc(protoView.element);
233+
elementsWithBindingsDynamic = DOM.getElementsByClassName(rootElementClone, NG_BINDING_CLASS);
238234
viewRootNodes = [rootElementClone];
239235
}
236+
var elementsWithBindings = ListWrapper.createFixedSize(elementsWithBindingsDynamic.length);
237+
for (var binderIdx = 0; binderIdx < elementsWithBindingsDynamic.length; ++binderIdx) {
238+
elementsWithBindings[binderIdx] = elementsWithBindingsDynamic[binderIdx];
239+
}
240+
240241
var binders = protoView.elementBinders;
241242
var boundTextNodes = [];
242243
var boundElements = ListWrapper.createFixedSize(binders.length);
@@ -245,15 +246,21 @@ export class DomRenderer extends Renderer {
245246
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
246247
var binder = binders[binderIdx];
247248
var element;
249+
var childNodes;
248250
if (binderIdx === 0 && protoView.rootBindingOffset === 1) {
249-
element = rootElementClone;
251+
// Note: if the root element was a template,
252+
// the rootElementClone is a document fragment,
253+
// which will be empty as soon as the view gets appended
254+
// to a parent. So we store null in the boundElements array.
255+
element = protoView.isTemplateElement ? null : rootElementClone;
256+
childNodes = DOM.childNodes(rootElementClone);
250257
} else {
251258
element = elementsWithBindings[binderIdx - protoView.rootBindingOffset];
259+
childNodes = DOM.childNodes(element);
252260
}
253261
boundElements[binderIdx] = element;
254262

255263
// boundTextNodes
256-
var childNodes = DOM.childNodes(DOM.templateAwareRoot(element));
257264
var textNodeIndices = binder.textNodeIndices;
258265
for (var i = 0; i < textNodeIndices.length; i++) {
259266
ListWrapper.push(boundTextNodes, childNodes[textNodeIndices[i]]);

0 commit comments

Comments
 (0)