Comments (9)
probably best to use update
for it
e.g.
update(changedProperties) {
super.update(changedProperties);
if (changedProperties.has('firstName') || changedProperties.has('lastName') {
this.fullName = `${this.firstName} ${this.lastName}`.trim();
}
}
- no need for an extra decorators
- will only be updated once if any of the involved properties changed
- access it does not involve a function call
from lit-element.
As an extension to @cristinecula 's post:
So we also have fair amount of logic based on computed partial states in Polymer and decided to look into porting this behavior to Lit, in the form of https://github.com/Neovici/computing-lit-element
It's not feature complete (no support for wildcards/paths) but it did make a sample component very convenient to migrate: Neovici/cosmoz-treenode@v3.0.1...v4.0.1#diff-4dfb1d30ec99074e5e06658034dd2775
The implementation is very compact (https://github.com/Neovici/computing-lit-element/blob/master/src/computingMixin.js#L43) and works like this:
When the element gets constructed, we analyze the properties to find the computed ones, and also find all dependency properties (we have to expand any computed properties we depend on), this analysis is only performed once.
In the update()
lifecycle method of a lit-element (https://lit-element.polymer-project.org/guide/lifecycle#update), changedProperties
are available to analyze, and it invokes the rendering with lit-html.
Because of this, when we override this method, we call the super.update();
at the end, to make sure our computed properties are a part of the same render cycle.
The trickiest part is in the loop. As we update the computed properties, they themselves get added to the changedProperties
array while we iterate through it, so we actually catch the whole dependency tree of computed properties during the loop itself, and everything gets updated in the same render.
This all can be conveniently packaged in a mixin so the lit-elements that needs this functionality can just, well, mix it in.
We are looking into doing the same for notify
to make a nice (interim) compatibility layer between lit-element and Polymer.
Hope this is useful for people ending up here :)
from lit-element.
We currently do not plan to add observers of computed properties. The idea is that you should generally use _render
and if necessary _didRender
.
Our experience from PolymerElement
has led us to believe that providing a library feature ("observers") to route changes to specific functions is not a good return on investment v. letting users just write the necessary code.
The reason for omitting "computed properties" is similar. In general, you can compute necessary values for rendering directly in _render
. If you have computed public properties, these should not provoke rendering (not be in properties
) and can be set in _didRender
.
from lit-element.
For properties that don't cause a render directly, setters seem to be a good replacement. I'm currently porting an app to LitElement, the app uses app-route
, so for an element that used to have an observer on the route
passed into it, I now have
set route (route) {
fetch(`some/thing/${route.path}`).then(resp => {
this.someDeclaredProperty = somethingBasedOn(resp)
})
}
And everything re-renders correctly after the fetch is done.
from lit-element.
kenchris/lit-element#15 offers a way to implement own observers in a didRender()
callback.
I suppose computedProperties can easily be done by doing ${this._computeAnotherField(field)}
in own instance method.
from lit-element.
Definitely agree that listing observers in property config in PolymerElement, rather than handling it functionally, was kinda clunky.
But for the use-case of reacting to properties that shouldn't cause a render, would it make sense to document the _propertiesChanged
callback from Polymer's property mixin in LitElement (perhaps as part of #37)?
from lit-element.
It's okay to replace observers with setters but getters lack memorization from Polymer computed properties.
If you access getter property multiple times from render it will be calculated each time. Even if you cache getter value inside render function it is still calculated on each render and not when dependent properties has changed.
For now I'm using my own decorator Gist
But I think it would be great to have something similar from lit-element module
@computed('firstName', 'lastName')
get fullName() {
return `${this.firstName} ${this.lastName}`.trim();
}
from lit-element.
actually, I was soooo wrong 🙈
update
is already patched e.g. it's not sync...
I could not find a public api that allows for sync logging
or computed properties
.
Opened a new issue #643
from lit-element.
You can achieve something similar to Polymer with this mixin:
const PropertyComputing = (base) => class extends base {
updated(changedProperties) {
super.updated(changedProperties);
Object.entries(this.constructor.properties)
.filter(([key, value]) => typeof value.compute === 'string')
.forEach(([key, value]) => {
if(value.deps.some(k => changedProperties.has(k))) {
this[key] = this[value.compute](...value.deps.map(dep => this[dep]))
}
})
}
}
class MyElement extends PropertyComputing(LitElement) {
static get properties() {
return {
prop1: { type: Number },
prop2: { type: Number },
comp: { type: Number, deps: ['prop1', 'prop2'], compute: '_computeComp'},
comp2: { type: Number, deps: ['prop1', 'comp'], compute: '_computeComp2'},
};
}
https://stackblitz.com/edit/sbcgaj?file=my-element.js
from lit-element.
Related Issues (20)
- Typescript error on latest build HOT 1
- mixins don't work when using ESNext in tsconfig to compile HOT 1
- Error throw when accessing queryAssignedNodes getter (No version >2.4.0) HOT 1
- Support for contexts? HOT 2
- Persistance? HOT 5
- idempotent/soft customElement decorator HOT 1
- state() is shown as deprecated in LitElement 2.5 HOT 1
- Should not be necessary to copy TemplateResult
- jsdelivr/+esm: [object Object] HOT 1
- Nested components, slot and text styling HOT 1
- Git tags are not in sync with npm tags HOT 2
- No release major/minor branches available for reference. HOT 2
- Move tests and benchmarks to GitHub Actions
- Accessibility => lit-element + Google Chrome Screen Reader Extension => UI Design is Changed HOT 3
- Property does not re-render when fired from custom event HOT 4
- Add a way to know when rendering of an element, and ALL its sub-elements, is finished HOT 3
- Litelement Boolean property returns undefined in when not set HOT 6
- Forward Compatibility With Lit 2 misleading HOT 2
- Starter projects missing in getting started documentation HOT 1
- How do you get the actual click event target? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lit-element.