【问题标题】:Lit-element children component not re rendering JS code based on updated propsLit-element 子组件不会根据更新的 props 重新渲染 JS 代码
【发布时间】:2020-10-18 09:44:35
【问题描述】:

Lit-Element 更新的 .props 不调用子组件的完全重新渲染,即当父组件更新位置时,子组件的 firstUpdated() 内的 javascript 代码基于从父组件传入的 .props 构造传单地图和城市,它不会使用新的位置和城市重新渲染地图。

当用户单击按钮将位置从西雅图更新到多伦多时,父母道具会更新并传递给孩子,但是地图不会自行重建,我如何强制地图“重建”(重新渲染)基于传递给孩子的新 .props ??

Git repo for my working sample code

谢谢! :) 连续几天一直在为此苦苦挣扎 - 仅供参考,是 Lit-Element 的新手。

Index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link type="text/css" href="./styles.css"
  <script src="./webcomponents/webcomponents-loader.js"></script>
  <script>
    if (!window.customElements) { document.write('<!--'); }
  </script>
  <script src="./webcomponents/custom-elements-es5-adapter.js"></script>
  <!-- ! DO NOT REMOVE THIS COMMENT, WE NEED ITS CLOSING MARKERS -->
</head>
<body>

  <app-view></app-view>

</body>
</html>

Index.js:

import './views/app-view.js'

父组件 app-view.js

import { html, LitElement } from 'lit-element';
import './esri-map.js'

class AppView extends LitElement{
  
  static get properties() {
    return {
      location: { type: Object },
      city: { type: String }
    }
  }
  
  constructor() {
    super();
    // set fallback location to seattle -- GET will pull in coordinates for Toronto
    this.location = { lat: "47.608013", long: "-122.335167" }
    this.city = "Seattle"
  }

  render() {
    return html`
    <style>
      #app-container{
        width: 100%,;
        height: 100%;
        display: flex;
      }
      #map-container{
        flex-grow: 1;
        height: 800px;
      }
    </style>
    <button @click=${ (event) => this.updateLocation() }
    >Set to Toronto
    </button>
    <div id="app-container">
      <div id="map-container">
        <esri-map 
          .location=${this.location}
          .city=${this.city}  
        >
        </esri-map>
      </div>
    </div>
    `;
  }

  updateLocation(){
    var oldLocation = this.location;  
    this.location = { lat: "43.651070", long: "-79.347015"} // Set to Toronto
    this.city = "Toronto";  // Set to Toronto
    console.log("New location is: " + this.city)
    console.log("Coordinates: ");
    console.log(this.location);
  }

}

customElements.define('app-view', AppView);

子组件

import { html, LitElement } from 'lit-element';
import * as L from 'leaflet';
import * as esri from 'esri-leaflet';

class EsriMap extends LitElement{
  static get properties() {
    return {
      location: { type: Object }, // prop passed from parent
      city: { type: String } // prop passed from parent
    }
  }

  render() {
    return html`
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"/>
    <style>
      #map{
        height: 100%;
        width: 100%;
      }
    </style>
    <h2>Current City: ${this.city} </h2>
    <h3>Coordinates: Lat: ${this.location.lat}</h3>
    <div id="map"></div>
    `
  }

  firstUpdated() {
    const mapNode = this.shadowRoot.querySelector('#map');
    
    // Render map with props from parent component
    var map = L.map(mapNode, {
      maxZoom: 18,
      minZoom: 2,
    }).setView([this.location.lat, this.location.long],8); // [Lat,Lng]
    const esriLayer = esri.basemapLayer('Streets');
    map.addLayer(esriLayer);

    // Render circle with props from parent component
    var circle = L.circle([this.location.lat, this.location.long], {
      color: 'red',
      fillColor: '#f03',
      fillOpacity: 0.5,
      radius: 20000,
    }).addTo(map);
  }

}

customElements.define('esri-map', EsriMap);

【问题讨论】:

    标签: lit-element lit-html


    【解决方案1】:

    当属性改变时,render() 函数被调用。

    firstUpdated() 仅在第一次更新后调用,而不是在每次属性更改时调用。

    试试这个:

    updated(changedProps) {
      if (changedProps.has('location')) {
        this._setMap();
      }
    }
    
    _setMap() {
      const mapNode = this.shadowRoot.querySelector('#map');
      
      if (mapNode == null || this.location == null) {
        return;
      }
        
        // Render map with props from parent component
      var map = L.map(mapNode, {
          maxZoom: 18,
          minZoom: 2,
        }).setView([this.location.lat, this.location.long],8); // [Lat,Lng]
        const esriLayer = esri.basemapLayer('Streets');
        map.addLayer(esriLayer);
    
        // Render circle with props from parent component
      var circle = L.circle([this.location.lat, this.location.long], {
          color: 'red',
          fillColor: '#f03',
          fillOpacity: 0.5,
          radius: 20000,
        }).addTo(map);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-08-30
      • 2020-02-13
      • 2020-04-18
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      • 2016-12-30
      • 2021-04-26
      • 2018-08-12
      相关资源
      最近更新 更多