Eliminate _renderPendingAttach. Test and fix x-repeat in document.

This commit is contained in:
Kevin Schaaf
2015-04-21 14:23:20 -07:00
parent cfea9323ae
commit b9a163e34f
4 changed files with 127 additions and 40 deletions

View File

@@ -29,7 +29,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
return;
}
// `archetype` is the prototype of the anonymous
// class created by the templatizer
// class created by the templatizer
var archetype = Object.create(Polymer.Base);
// normally Annotations.parseAnnotations(template) but
// archetypes do special caching
@@ -80,7 +80,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
if (c) {
var rootDataHost = archetype._rootDataHost;
if (rootDataHost) {
Polymer.Annotations.prepElement =
Polymer.Annotations.prepElement =
rootDataHost._prepElement.bind(rootDataHost);
}
archetype._notes = c._notes ||
@@ -88,7 +88,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
c._notes = archetype._notes;
Polymer.Annotations.prepElement = null;
archetype._parentProps = c._parentProps;
}
}
else {
console.warn('no _content');
}
@@ -100,7 +100,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
// Sets up accessors on the template to call abstract _forwardParentProp
// API that should be implemented by Templatizer users to get parent
// properties to their template instances. These accessors are memoized
// properties to their template instances. These accessors are memoized
// on the archetype and copied to instances.
_prepParentProperties: function(archetype) {
var parentProps = this._parentProps = archetype._parentProps;
@@ -169,7 +169,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
dataHost.dataHost[sub] = value;
} else {
dataHost.notifyPath('_parent_' + subPath, value);
}
}
}
// Extension point for Templatizer sub-classes
if (dataHost._forwardInstancePath) {
@@ -189,8 +189,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
_constructorImpl: function(model, host) {
var rootDataHost = host._getRootDataHost();
this.listen = rootDataHost.listen.bind(rootDataHost);
this._rootDataHost = rootDataHost;
if (rootDataHost) {
this.listen = rootDataHost.listen.bind(rootDataHost);
this._rootDataHost = rootDataHost;
}
this._setupConfigure(model);
this._pushHost(host);
this.root = this.instanceTemplate(this._template);
@@ -210,12 +212,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
model.parent = model.parent || {};
for (var prop in this._parentProps) {
model.parent[prop] = this['_parent_' + prop];
}
}
}
return new this.ctor(model, this);
}
// TODO(sorvell): note, using the template as host is ~5-10% faster if
// TODO(sorvell): note, using the template as host is ~5-10% faster if
// elements have no default values.
// _constructorImpl: function(model, host) {
// this._setupConfigure(model);
@@ -232,7 +234,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
// stamp: function(model) {
// return new this.ctor(model, this.host);
// }
};

View File

@@ -48,9 +48,9 @@ Example:
</script>
</dom-module>
```
```
Notifications for changes to items sub-properties will be forwarded to template
Notifications for changes to items sub-properties will be forwarded to template
instances, which will update via the normal structured data notification system.
Mutations to the `items` array itself (`push`, `pop`, `splice`, `shift`,
@@ -78,7 +78,7 @@ isEngineer: function(item) {
Then the `observe` property should be configured as follows:
```html
<template is="x-repeat" items="{{employees}}"
<template is="x-repeat" items="{{employees}}"
filter="isEngineer" observe="type manager.type">
```
@@ -170,15 +170,11 @@ Then the `observe` property should be configured as follows:
if (!this.ctor) {
this.templatize(this);
}
if (this._renderPendingAttach) {
this._renderPendingAttach = false;
this.render();
}
},
_sortChanged: function() {
var dataHost = this._getRootDataHost();
this._sortFn = this.sort && (typeof this.sort == 'function' ?
this._sortFn = this.sort && (typeof this.sort == 'function' ?
this.sort : dataHost[this.sort].bind(this.host));
if (this.items) {
this.debounce('render', this.render);
@@ -187,7 +183,7 @@ Then the `observe` property should be configured as follows:
_filterChanged: function() {
var dataHost = this._getRootDataHost();
this._filterFn = this.filter && (typeof this.filter == 'function' ?
this._filterFn = this.filter && (typeof this.filter == 'function' ?
this.filter : dataHost[this.filter].bind(this.host));
if (this.items) {
this.debounce('render', this.render);
@@ -195,7 +191,7 @@ Then the `observe` property should be configured as follows:
},
_observeChanged: function() {
this._observePaths = this.observe &&
this._observePaths = this.observe &&
this.observe.replace('.*', '.').split(' ');
},
@@ -237,16 +233,7 @@ Then the `observe` property should be configured as follows:
},
render: function(splices) {
// TODO(kschaaf): should actually queue splices also
if (!this.isAttached) {
// Render must follow attachment
this._renderPendingAttach = true;
return;
}
this._render(splices);
},
_render: function(splices) {
this.flushDebouncer('render');
var c = this.collection;
if (splices) {
if (this._sortFn || splices[0].index == null) {
@@ -348,7 +335,7 @@ Then the `observe` property should be configured as follows:
var start = 0;
for (i=0; i<addedKeys.length; i++) {
start = this._insertRowIntoViewSort(start, addedKeys[i], pool);
}
}
}
},
@@ -400,7 +387,7 @@ Then the `observe` property should be configured as follows:
addedKeys = addedKeys.filter(function(a) {
return this._filterFn(c.getItem(a));
}, this);
filterDelta += (s.added.length - addedKeys.length);
filterDelta += (s.added.length - addedKeys.length);
}
var idx = s.index - filterDelta;
// Apply splices to keys
@@ -462,13 +449,13 @@ Then the `observe` property should be configured as follows:
var c = this.rows[i]._children;
for (var j=0; j<c.length; j++)
children.push(c[j]);
}
}
}
return children;
},
// Implements extension point from Templatizer
// Called as a side effect of a template instance path change, responsible
// Called as a side effect of a template instance path change, responsible
// for notifying items.<key-for-row>.<path> change up to host
_forwardInstancePath: function(row, root, subPath, value) {
if (root == 'item') {
@@ -484,7 +471,7 @@ Then the `observe` property should be configured as follows:
this.rows.forEach(function(row) {
row.parent[prop] = value;
row.notifyPath('parent.' + prop, value, true);
}, this);
}, this);
}
},
@@ -495,7 +482,7 @@ Then the `observe` property should be configured as follows:
if (this.rows) {
this.rows.forEach(function(row) {
row.notifyPath('parent.' + path, value, true);
}, this);
}, this);
}
},

View File

@@ -168,13 +168,15 @@ window.data = [
<dom-module id="x-nested-repeat">
<template>
<template id="repeater" is="x-repeat" items="{{items}}">
<x-foo prop="{{prop}}"
<x-foo on-test1="testHandler1"
prop="{{prop}}"
item-prop="{{item.prop}}"
parent-prop="{{parent.prop}}"
parent-item-prop="{{parent.item.prop}}">
</x-foo>
<template is="x-repeat" items="{{item.items}}">
<x-foo prop="{{prop}}"
<x-foo on-test2="testHandler2"
prop="{{prop}}"
item-prop="{{item.prop}}"
parent-prop="{{parent.prop}}"
parent-item-prop="{{parent.item.prop}}"
@@ -182,7 +184,8 @@ window.data = [
parent-parent-item-prop="{{parent.parent.item.prop}}">
</x-foo>
<template is="x-repeat" items="{{item.items}}">
<x-foo prop="{{prop}}"
<x-foo on-test3="testHandler3"
prop="{{prop}}"
item-prop="{{item.prop}}"
parent-prop="{{parent.prop}}"
parent-item-prop="{{parent.item.prop}}"
@@ -198,7 +201,19 @@ window.data = [
</dom-module>
<script>
Polymer({
is: 'x-nested-repeat'
is: 'x-nested-repeat',
testHandler1Count: 0,
testHandler2Count: 0,
testHandler3Count: 0,
testHandler1: function() {
this.testHandler1Count++;
},
testHandler2: function() {
this.testHandler2Count++;
},
testHandler3: function() {
this.testHandler3Count++;
}
});
</script>

View File

@@ -25,6 +25,30 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<x-nested-repeat id="unconfigured2" items="{{items}}"></x-nested-repeat>
</template>
<div id="inDocumentContainer">
<template id="inDocumentRepeater" is="x-repeat" items="{{items}}">
<x-foo prop="{{prop}}"
item-prop="{{item.prop}}">
</x-foo>
<template is="x-repeat" items="{{item.items}}">
<x-foo prop="{{prop}}"
item-prop="{{item.prop}}"
parent-prop="{{parent.prop}}"
parent-item-prop="{{parent.item.prop}}">
</x-foo>
<template is="x-repeat" items="{{item.items}}">
<x-foo prop="{{prop}}"
item-prop="{{item.prop}}"
parent-prop="{{parent.prop}}"
parent-item-prop="{{parent.item.prop}}"
parent-parent-prop="{{parent.parent.prop}}"
parent-parent-item-prop="{{parent.parent.item.prop}}">
</x-foo>
</template>
</template>
</template>
</div>
<script>
/*
@@ -127,6 +151,55 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
});
suite('nested un-configured x-repeat in document', function() {
test('basic rendering, downward item binding', function(done) {
inDocumentRepeater.items = window.data;
setTimeout(function() {
var stamped = Polymer.dom(inDocumentContainer).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect');
assert.equal(stamped[0].itemProp, 'prop-1');
assert.equal(stamped[0].$.bar.itemProp, 'prop-1');
assert.equal(stamped[1].itemProp, 'prop-1-1');
assert.equal(stamped[1].$.bar.itemProp, 'prop-1-1');
assert.equal(stamped[2].itemProp, 'prop-1-1-1');
assert.equal(stamped[2].$.bar.itemProp, 'prop-1-1-1');
assert.equal(stamped[3].itemProp, 'prop-1-1-2');
assert.equal(stamped[3].$.bar.itemProp, 'prop-1-1-2');
assert.equal(stamped[4].itemProp, 'prop-1-1-3');
assert.equal(stamped[4].$.bar.itemProp, 'prop-1-1-3');
assert.equal(stamped[13].itemProp, 'prop-2');
assert.equal(stamped[13].$.bar.itemProp, 'prop-2');
assert.equal(stamped[36].itemProp, 'prop-3-3-1');
assert.equal(stamped[36].$.bar.itemProp, 'prop-3-3-1');
assert.equal(stamped[37].itemProp, 'prop-3-3-2');
assert.equal(stamped[37].$.bar.itemProp, 'prop-3-3-2');
assert.equal(stamped[38].itemProp, 'prop-3-3-3');
assert.equal(stamped[38].$.bar.itemProp, 'prop-3-3-3');
done();
});
});
test('parent scope binding', function() {
var stamped = Polymer.dom(inDocumentContainer).querySelectorAll('*:not(template)');
assert.equal(stamped[1].parentItemProp, 'prop-1');
assert.equal(stamped[2].parentItemProp, 'prop-1-1');
assert.equal(stamped[2].parentParentItemProp, 'prop-1');
assert.equal(stamped[38].parentItemProp, 'prop-3-3');
assert.equal(stamped[38].parentParentItemProp, 'prop-3');
});
test('anonymous scope binding', function() {
var stamped = Polymer.dom(inDocumentContainer).querySelectorAll('*:not(template)');
stamped[1].$.bar.prop = 'changed';
assert.equal(stamped[1].prop, 'changed');
assert.equal(stamped[2].parentProp, 'changed');
assert.equal(stamped[3].parentProp, 'changed');
assert.equal(stamped[4].parentProp, 'changed');
});
});
suite('nested un-configured x-repeat', function() {
test('basic rendering, downward item binding', function(done) {
@@ -214,6 +287,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.equal(stamped[4].parentProp, 'changed');
});
test('event handlers', function() {
var stamped = Polymer.dom(unconfigured1.root).querySelectorAll('*:not(template)');
stamped[0].fire('test1');
assert.equal(unconfigured1.testHandler1Count, 1);
stamped[1].fire('test2');
assert.equal(unconfigured1.testHandler2Count, 1);
stamped[2].fire('test3');
assert.equal(unconfigured1.testHandler3Count, 1);
});
});
suite('array notification between two x-repeats', function() {