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.
This commit is contained in:
parent
2351896cc0
commit
24bc4b66d0
@ -209,34 +209,35 @@ export class DomRenderer extends Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_createView(protoView: DomProtoView, inplaceElement): DomView {
|
_createView(protoView: DomProtoView, inplaceElement): DomView {
|
||||||
var rootElementClone =
|
var rootElementClone;
|
||||||
isPresent(inplaceElement) ? inplaceElement : DOM.importIntoDoc(protoView.element);
|
|
||||||
var elementsWithBindingsDynamic;
|
var elementsWithBindingsDynamic;
|
||||||
if (protoView.isTemplateElement) {
|
|
||||||
elementsWithBindingsDynamic =
|
|
||||||
DOM.querySelectorAll(DOM.content(rootElementClone), NG_BINDING_CLASS_SELECTOR);
|
|
||||||
} else {
|
|
||||||
elementsWithBindingsDynamic = DOM.getElementsByClassName(rootElementClone, NG_BINDING_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
var elementsWithBindings = ListWrapper.createFixedSize(elementsWithBindingsDynamic.length);
|
|
||||||
for (var binderIdx = 0; binderIdx < elementsWithBindingsDynamic.length; ++binderIdx) {
|
|
||||||
elementsWithBindings[binderIdx] = elementsWithBindingsDynamic[binderIdx];
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewRootNodes;
|
var viewRootNodes;
|
||||||
if (protoView.isTemplateElement) {
|
if (isPresent(inplaceElement)) {
|
||||||
var childNode = DOM.firstChild(DOM.content(rootElementClone));
|
rootElementClone = inplaceElement;
|
||||||
viewRootNodes =
|
elementsWithBindingsDynamic = [];
|
||||||
[]; // TODO(perf): Should be fixed size, since we could pre-compute in in DomProtoView
|
viewRootNodes = [inplaceElement];
|
||||||
|
} else if (protoView.isTemplateElement) {
|
||||||
|
rootElementClone = DOM.importIntoDoc(DOM.content(protoView.element));
|
||||||
|
elementsWithBindingsDynamic =
|
||||||
|
DOM.querySelectorAll(rootElementClone, NG_BINDING_CLASS_SELECTOR);
|
||||||
|
var childNode = DOM.firstChild(rootElementClone);
|
||||||
|
// TODO(perf): Should be fixed size, since we could pre-compute in in DomProtoView
|
||||||
|
viewRootNodes = [];
|
||||||
// Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
|
// Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
|
||||||
while (childNode != null) {
|
while (childNode != null) {
|
||||||
ListWrapper.push(viewRootNodes, childNode);
|
ListWrapper.push(viewRootNodes, childNode);
|
||||||
childNode = DOM.nextSibling(childNode);
|
childNode = DOM.nextSibling(childNode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
rootElementClone = DOM.importIntoDoc(protoView.element);
|
||||||
|
elementsWithBindingsDynamic = DOM.getElementsByClassName(rootElementClone, NG_BINDING_CLASS);
|
||||||
viewRootNodes = [rootElementClone];
|
viewRootNodes = [rootElementClone];
|
||||||
}
|
}
|
||||||
|
var elementsWithBindings = ListWrapper.createFixedSize(elementsWithBindingsDynamic.length);
|
||||||
|
for (var binderIdx = 0; binderIdx < elementsWithBindingsDynamic.length; ++binderIdx) {
|
||||||
|
elementsWithBindings[binderIdx] = elementsWithBindingsDynamic[binderIdx];
|
||||||
|
}
|
||||||
|
|
||||||
var binders = protoView.elementBinders;
|
var binders = protoView.elementBinders;
|
||||||
var boundTextNodes = [];
|
var boundTextNodes = [];
|
||||||
var boundElements = ListWrapper.createFixedSize(binders.length);
|
var boundElements = ListWrapper.createFixedSize(binders.length);
|
||||||
@ -245,15 +246,21 @@ export class DomRenderer extends Renderer {
|
|||||||
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
|
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
|
||||||
var binder = binders[binderIdx];
|
var binder = binders[binderIdx];
|
||||||
var element;
|
var element;
|
||||||
|
var childNodes;
|
||||||
if (binderIdx === 0 && protoView.rootBindingOffset === 1) {
|
if (binderIdx === 0 && protoView.rootBindingOffset === 1) {
|
||||||
element = rootElementClone;
|
// Note: if the root element was a template,
|
||||||
|
// the rootElementClone is a document fragment,
|
||||||
|
// which will be empty as soon as the view gets appended
|
||||||
|
// to a parent. So we store null in the boundElements array.
|
||||||
|
element = protoView.isTemplateElement ? null : rootElementClone;
|
||||||
|
childNodes = DOM.childNodes(rootElementClone);
|
||||||
} else {
|
} else {
|
||||||
element = elementsWithBindings[binderIdx - protoView.rootBindingOffset];
|
element = elementsWithBindings[binderIdx - protoView.rootBindingOffset];
|
||||||
|
childNodes = DOM.childNodes(element);
|
||||||
}
|
}
|
||||||
boundElements[binderIdx] = element;
|
boundElements[binderIdx] = element;
|
||||||
|
|
||||||
// boundTextNodes
|
// boundTextNodes
|
||||||
var childNodes = DOM.childNodes(DOM.templateAwareRoot(element));
|
|
||||||
var textNodeIndices = binder.textNodeIndices;
|
var textNodeIndices = binder.textNodeIndices;
|
||||||
for (var i = 0; i < textNodeIndices.length; i++) {
|
for (var i = 0; i < textNodeIndices.length; i++) {
|
||||||
ListWrapper.push(boundTextNodes, childNodes[textNodeIndices[i]]);
|
ListWrapper.push(boundTextNodes, childNodes[textNodeIndices[i]]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user