Skip to content

Commit 5c393f8

Browse files
author
Steven Orvell
committed
Merge branch 'master' into early-request-update
2 parents 4f4f078 + 34c9568 commit 5c393f8

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2020

2121
### Fixed
2222
* Initial update is scheduled at construction time rather than connected time ([#594](https://github.com/Polymer/lit-element/issues/594)).
23+
* A reflecting property set immediately after a corresponding attribute
24+
now reflects properly ([#592](https://github.com/Polymer/lit-element/issues/592)).
2325
* Properties annotated with the `@query` and `@queryAll` decorators will now
2426
survive property renaming optimizations when used with tsickle and Closure JS
2527
Compiler.

src/lib/updating-element.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -579,25 +579,29 @@ export abstract class UpdatingElement extends HTMLElement {
579579
*/
580580
requestUpdate(name?: PropertyKey, oldValue?: unknown) {
581581
let shouldRequestUpdate = true;
582-
// if we have a property key, perform property update steps.
583-
if (name !== undefined && !this._changedProperties.has(name)) {
582+
// If we have a property key, perform property update steps.
583+
if (name !== undefined) {
584584
const ctor = this.constructor as typeof UpdatingElement;
585585
const options =
586586
ctor._classProperties!.get(name) || defaultPropertyDeclaration;
587587
if (ctor._valueHasChanged(
588588
this[name as keyof this], oldValue, options.hasChanged)) {
589-
// track old value when changing.
590-
this._changedProperties.set(name, oldValue);
591-
// add to reflecting properties set
589+
if (!this._changedProperties.has(name)) {
590+
this._changedProperties.set(name, oldValue);
591+
}
592+
// Add to reflecting properties set.
593+
// Note, it's important that every change has a chance to add the
594+
// property to `_reflectingProperties`. This ensures setting
595+
// attribute + property reflects correctly.
592596
if (options.reflect === true &&
593597
!(this._updateState & STATE_IS_REFLECTING_TO_PROPERTY)) {
594598
if (this._reflectingProperties === undefined) {
595599
this._reflectingProperties = new Map();
596600
}
597601
this._reflectingProperties.set(name, options);
598602
}
599-
// abort the request if the property should not be considered changed.
600603
} else {
604+
// Abort the request if the property should not be considered changed.
601605
shouldRequestUpdate = false;
602606
}
603607
}

src/test/lib/updating-element_test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,4 +2236,32 @@ suite('UpdatingElement', () => {
22362236
await a.updateComplete;
22372237
assert.isTrue(updated);
22382238
});
2239+
2240+
test('property reflects after setting attribute in same update cycle', async () => {
2241+
class A extends UpdatingElement {
2242+
2243+
foo?: boolean;
2244+
bar?: string;
2245+
2246+
static get properties() {
2247+
return {
2248+
foo: {type: Boolean, reflect: true},
2249+
bar: {type: String, reflect: true}
2250+
};
2251+
}
2252+
2253+
}
2254+
customElements.define(generateElementName(), A);
2255+
const a = new A();
2256+
container.appendChild(a);
2257+
a.setAttribute('foo', '');
2258+
a.removeAttribute('foo');
2259+
a.foo = true;
2260+
await a.updateComplete;
2261+
assert.isTrue(a.hasAttribute('foo'));
2262+
a.setAttribute('bar', 'hi');
2263+
a.bar = 'yo';
2264+
await a.updateComplete;
2265+
assert.equal(a.getAttribute('bar'), 'yo');
2266+
});
22392267
});

0 commit comments

Comments
 (0)