9

我不知道如何观察 LitElement 中的属性变化。

我一直在尝试这些方法,但我无法让这些工作:

  static get properties() {
    return {
      temp1:String,
      temp2: {
       type:String,
       observer: '_temp2Changed'
        }
  };

  temp1Changed(newValue, oldValue){
    console.log("temp1 changed")
  }
  _temp2Changed(newValue, oldValue){
    console.log("temp2 changed")
  }
4

6 回答 6

11

版本 0.6.0+

首先,您必须指定元素属性。您可以通过创建一个静态 getter 来做到这一点,该 getter 返回一个对象,包括它们的名称作为键及其与属性相关的配置。

updated更改的属性导致重新渲染时,将调用生命周期方法。第一个参数将在更新之前返回值。

class MyComponent extends LitElement {
  static get properties() {
    return {
      foo: {}
    };
  }

  constructor() {
    super();
    this.foo = 0;
    setInterval(() => this.foo++, 1000);
  }

  updated(changedProperties) {
    console.log(changedProperties); // logs previous values
    console.log(this.foo); // logs current value
  }

  render() {
    return html`${this.foo}`;
  }
}

customElements.define("my-component", MyComponent);
于 2018-09-22T09:38:06.407 回答
3

我个人重写了“requestUpdate”方法,以便在渲染之前了解更改。

我的用例是拦截“标签”属性的更改以触发异步数据请求。

下面的片段(在 TypeScript 中):

@customElement('my-element')
export default class MyElement extends LitElement {

    @property({type: String})
    label: string | null = null;

    @property({attribute: false})
    private isLoading: boolean = false;

    @property({attribute: false, noAccessor: true})
    private data: MyData | null = null;

    protected render() {/*some code*/}

    requestUpdate(name?: PropertyKey, oldValue?: unknown) {
        if(name && name == "label" && this.label !== oldValue) {
            this.isLoading = true;
            requestData(this.label, this._callbackData);
        }
        return super.requestUpdate(name, oldValue);
    }

    private _callbackData(data: MyData}) {
        this.data = data;
        this.isLoading = false;
    }

}

通过这种方式,我的元素只呈现了两次:一次使用新标签并加载为 true,然后在数据可用时加载另一次。

于 2019-03-06T10:57:11.457 回答
2

属性“hasChanged”选项:

您可以在静态属性 getter 中的属性声明中定义此“hasChanged”选项。就像您使用“类型”选项一样。

hasChanged 应该返回 true 来更新元素。

myProp: { hasChanged(newVal, oldVal) {
 // compare newVal and oldVal
 // return `true` if an update should proceed
}}

看看这里

生命周期方法:更新

有一个名为“updated”的生命周期方法,每次任何属性更改时都会触发该方法。

此方法将“changedProperties”及其先前值作为参数接收,因此您可以将它们与当前值进行比较,然后决定您想用它做什么。

在此处查看“更新”文档。

于 2019-08-29T07:05:49.330 回答
1

只要属性在您的“_render”方法中定义,LitElement 会在每次属性更改时自动重新渲染。

这在 LitElement自述文件中有说明:

对更改做出反应:LitElement 通过异步渲染对属性和属性的更改做出反应,确保更改是批处理的。这减少了开销并保持了一致的状态。

例如:

_render({firstName, lastName}) {
  return html`
    <div> Hello ${firstName} ${lastName} </div>
  `
};

每次您的 firstName 和 lastName 属性更改时都会重新渲染。我希望这提供了一点清晰。

于 2018-09-13T13:34:45.270 回答
0

我从 Polymer 的 PWA 入门套件中找到了一个解决方案。

将以下内容添加到您的元素定义中:

_propertiesChanged(props, changed, oldProps) {
    console.log("_propertiesChanged(props, changed, oldProps):");
    console.log(props);    
    console.log(changed);  
    console.log(oldProps); 
    if (changed && 'temp1' in changed) {
      console.log("if temp1:"+changed.temp1);
    }
    super._propertiesChanged(props, changed, oldProps); //This is needed here
}

console output:
_propertiesChanged(props, changed, oldProps):
{temp1: "newVal1", temp2: "val2"}
{temp1: "newVal1"}
{temp1: "val1"}
if temp1:newVal1
于 2018-05-18T09:41:42.563 回答
0

实现 shouldUpdate() 方法。来源在这里。

控制是否应继续更新。实施shouldUpdate以指定哪些属性更改应导致更新。默认情况下,此方法始终返回 true。

function shouldUpdate(changedProperties: Map<any, any>) {
    changedProperties.forEach((oldValue, propName) => {
        const newValue = JSON.stringify(this[propName]);
        console.log(`${propName} changed. oldValue: ${oldValue} newValue: ${newValue}`);
    });
    return true;
}
于 2020-09-30T11:13:55.437 回答