Skip to content

Commit 79f66f2

Browse files
kevinpschaafKate
authored andcommitted
[docs] Update docs to reflect #454 change to remove accessor wrapping (#460)
* Update docs to reflect #454 change to remove accessor wrapping Since we no longer wrap existing accessors, the language and example in #accessors-custom is updated to indicate the user must manually call `requestUpdate`. In addition, since `noAccessor` is _only_ needed now in a pretty esoteric case (extending a superclass and changing metadata for a declared property _that also has a custom accessor_), the code example in that section is simplified. * Code samples for accessors with subclassing * Update per feedback
1 parent 363358e commit 79f66f2

File tree

8 files changed

+66
-121
lines changed

8 files changed

+66
-121
lines changed

docs/_guide/properties.md

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -385,78 +385,59 @@ this.myProp = 'hi'; // invokes myProp's generated property accessor
385385
386386
Generated accessors automatically call `requestUpdate`, initiating an update if one has not already begun.
387387
388-
### Create custom property accessors {#accessors-custom}
388+
### Create your own property accessors {#accessors-custom}
389389
390-
To specify how getting and setting works for a property, create custom accessors:
390+
To specify how getting and setting works for a property, you can define your own property accessors. For example:
391391
392392
```js
393-
// Declare a property
394393
static get properties() { return { myProp: { type: String } }; }
395394

396-
// Custom accessors
397-
set myProp(value) { ... /* Custom setter */ }
398-
get myProp() { ... /* Custom getter */ }
395+
set myProp(value) {
396+
const oldValue = this.myProp;
397+
// Implement setter logic here...
398+
this.requestUpdate('myProp', oldValue);
399+
}
400+
get myProp() { ... }
399401

400402
...
401403

402404
// Later, set the property
403-
this.myProp = 'hi'; // Invokes generated accessor, which calls custom accessor
405+
this.myProp = 'hi'; // Invokes your accessor
404406
```
405407
406-
When you create custom property accessors for a property, LitElement still generates its own accessors unless you specify otherwise ([see below](#accessors-noaccessor)). The generated setter:
408+
If your class defines its own accessors for a property, LitElement will not overwrite them with generated accessors. If your class does not define accessors for a property, LitElement will generate them, even if a superclass has defined the property or accessors.
407409
408-
* Saves the previous property value.
409-
* Calls your custom setter.
410-
* Requests an update, supplying the property name and its old value to the update lifecycle.
411-
412-
### Prevent LitElement from generating a property accessor {#accessors-noaccessor}
410+
The setters that LitElement generates automatically call `requestUpdate`. If you write your own setter you must call `requestUpdate` manually, supplying the property name and its old value.
413411
414-
To prevent LitElement from generating property accessors, set `noAccessor` to `true` in the property declaration:
412+
**Example**
415413
416414
```js
417-
static get properties() { return {
418-
// Don't generate accessors for myProp
419-
myProp: { type: Number, noAccessor: true }
420-
421-
// Do generate accessors for aProp
422-
aProp: { type: String }
423-
}; }
424-
425-
// Create custom accessors for myProp
426-
set myProp(value) { this._myProp = Math.floor(value); }
427-
get myProp() { return this._myProp; }
428-
429-
updated(changedProperties) { ... /* no changedProperties entry for myProp */ }
430-
431-
...
432-
// later...
433-
this.myProp = Math.random()*10; // Invokes custom setter; no generated setter
434-
this.aProp = 'hi'; // Invokes generated setter
415+
{% include projects/properties/customsetter/my-element.js %}
435416
```
436417
437-
In the example above:
418+
### Prevent LitElement from generating a property accessor {#accessors-noaccessor}
438419
439-
* No update request will be made when `this.myProp = ...` is executed.
440-
* The update requested as a result of `this.aProp = ...` will still capture `myProp`'s new value.
441-
* The change to `myProp` won't register in the element update lifecycle.
420+
In rare cases, a subclass may need to change or add property options for a property that exists on its superclass.
442421
443-
To handle update requests and property options in a custom setter, call `this.requestUpdate('propertyName', oldValue)`:
422+
To prevent LitElement from generating a property accessor that overwrites the superclass's defined accessor, set `noAccessor` to `true` in the property declaration:
444423
445424
```js
446-
set myProp(value) {
447-
let oldValue = this._myProp;
448-
this._myProp = Math.floor(value);
449-
this.requestUpdate('myProp', oldValue);
450-
}
425+
static get properties() {
426+
return { myProp: { type: Number, noAccessor: true } };
427+
}
451428
```
452429
453-
**Example: Custom property accessors**
430+
You don't need to set `noAccessor` when defining your own accessors.
431+
432+
**Example**
433+
434+
**Subclass element**
454435
455436
```js
456-
{% include projects/properties/customsetter/my-element.js %}
437+
{% include projects/properties/accessorssubclassing/sub-element.js %}
457438
```
458439
459-
{% include project.html folder="properties/customsetter" openFile="my-element.js" %}
440+
{% include project.html folder="properties/accessorssubclassing" openFile="sub-element.js" %}
460441
461442
## Configure property changes {#haschanged}
462443

docs/_includes/projects/properties/accessorssubclassing/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</head>
1212

1313
<body>
14-
<my-element></my-element>
14+
<sub-element prop="6.2344235"></sub-element>
1515
</body>
1616

1717
</html>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
import './super-element.js';
2-
import './my-element.js';
2+
import './sub-element.js';

docs/_includes/projects/properties/accessorssubclassing/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"title": "lit-element code sample",
33
"description": "lit-element code sample",
44
"files": [
5-
"my-element.js",
65
"super-element.js",
6+
"sub-element.js",
77
"index.html",
88
"index.ts"
99
],

docs/_includes/projects/properties/accessorssubclassing/my-element.js

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { SuperElement } from './super-element.js';
2+
3+
class SubElement extends SuperElement {
4+
static get properties() {
5+
return { prop: { reflectToAttribute: true, noAccessor: true } };
6+
}
7+
}
8+
9+
customElements.define('sub-element', SubElement);
Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,30 @@
11
import { LitElement, html } from 'lit-element';
22

33
export class SuperElement extends LitElement {
4-
static get properties() { return {
5-
prop1: { type: Number }
6-
};}
7-
8-
get prop1() {
9-
console.log('custom getter');
10-
return this._prop1;
4+
static get properties() {
5+
return { prop: { type: Number } };
116
}
127

13-
set prop1(value) {
14-
console.log('custom setter');
15-
this._prop1 = Math.floor(value/10);
8+
set prop(val) {
9+
let oldVal = this._prop;
10+
this._prop = Math.floor(val);
11+
this.requestUpdate('prop', oldVal);
1612
}
1713

14+
get prop() { return this._prop; }
15+
1816
constructor() {
1917
super();
20-
this.prop1 = 0;
18+
this._prop = 0;
2119
}
2220

2321
render() {
24-
return html`
25-
<p>prop1: ${this.prop1}</p>
26-
<button @click="${this.changeProperty}">change property</button>
27-
`;
28-
}
29-
30-
changeProperty() {
31-
let randy = Math.floor(Math.random()*100);
32-
console.log('Setting to:', randy);
33-
this.prop1 = randy;
22+
return html`
23+
<p>prop: ${this.prop}</p>
24+
<button @click="${() => { this.prop = Math.random()*10; }}">
25+
change prop
26+
</button>
27+
`;
3428
}
3529
}
36-
3730
customElements.define('super-element', SuperElement);
Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,30 @@
11
import { LitElement, html } from 'lit-element';
22

33
class MyElement extends LitElement {
4-
static get properties() { return {
5-
prop1: { type: Number, noAccessor: true },
6-
prop2: { type: Number },
7-
prop3: { type: Number, noAccessor: true },
8-
};}
4+
static get properties() {
5+
return { prop: { type: Number } };
6+
}
97

10-
set prop1(newVal) { this._prop1 = Math.floor(newVal); }
11-
set prop2(newVal) { this._prop2 = Math.floor(newVal); }
12-
set prop3(newVal) {
13-
let oldVal = this._prop3;
14-
this._prop3 = Math.floor(newVal);
15-
this.requestUpdate('prop3', oldVal);
8+
set prop(val) {
9+
let oldVal = this._prop;
10+
this._prop = Math.floor(val);
11+
this.requestUpdate('prop', oldVal);
1612
}
1713

18-
get prop1() { return this._prop1; }
19-
get prop2() { return this._prop2; }
20-
get prop3() { return this._prop3; }
14+
get prop() { return this._prop; }
2115

2216
constructor() {
2317
super();
24-
this._prop1 = 0;
25-
this._prop2 = 0;
26-
this._prop3 = 0;
18+
this._prop = 0;
2719
}
2820

2921
render() {
3022
return html`
31-
<p>prop1: ${this.prop1}</p>
32-
<p>prop2: ${this.prop2}</p>
33-
<p>prop3: ${this.prop3}</p>
34-
35-
<button @click="${this.getNewVal}">change properties</button>
23+
<p>prop: ${this.prop}</p>
24+
<button @click="${() => { this.prop = Math.random()*10; }}">
25+
change prop
26+
</button>
3627
`;
3728
}
38-
39-
updated(changedProperties) {
40-
changedProperties.forEach((oldValue, propName) => {
41-
console.log(`${propName} changed. oldValue: ${oldValue}`);
42-
});
43-
}
44-
45-
getNewVal() {
46-
let newVal = Math.random()*10;
47-
this.prop1 = newVal;
48-
this.prop2 = newVal;
49-
this.prop3 = newVal;
50-
}
5129
}
5230
customElements.define('my-element', MyElement);

0 commit comments

Comments
 (0)