Git Product home page Git Product logo

Comments (9)

daKmoR avatar daKmoR commented on July 26, 2024 2

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.

nomego avatar nomego commented on July 26, 2024 2

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.

sorvell avatar sorvell commented on July 26, 2024 1

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.

valpackett avatar valpackett commented on July 26, 2024 1

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.

ernsheong avatar ernsheong commented on July 26, 2024

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.

madeleineostoja avatar madeleineostoja commented on July 26, 2024

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.

mkozak0108 avatar mkozak0108 commented on July 26, 2024

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.

daKmoR avatar daKmoR commented on July 26, 2024

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.

cristinecula avatar cristinecula commented on July 26, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.