简体   繁体   English

渲染 function 内的模板未解析 - LitElement

[英]Template inside render function is not resolving - LitElement

I was trying to get a list through an ajax call but before it gets resolved, render() method is being called and the template fragment dependent on the Promise was not able to resolve and throws undefined.我试图通过 ajax 调用获取列表,但在解决之前,正在调用render()方法,并且依赖于 Promise 的模板片段无法解析并抛出未定义。

Question : How to show a loader till I get the data from the Promise?问题:在我从 Promise 获取数据之前,如何显示加载程序?

import {
    LitElement,
    html
} from 'lit-element';

class EmpComponent extends LitElement {
    constructor() {
        super();
        this.data = this.getEmpData();
    }

    getEmpData() {
        fetch('../../../emp-data.json')
            .then(
                function(response) {
                    if (response.status !== 200) {
                        console.log('Looks like there was a problem. Status Code: ' +
                            response.status);
                        return;
                    }

                    response.json().then(data => data);
                }
            )
            .catch(function(err) {
                console.log('Fetch Error :-S', err);
            });
    }

    render() {
        <div>
            ${this.data.map(emp => emp.active ? this.dataTemplate(emp) : '')} 
        </div>
    }
}

customElements.define('emp-component', EmpComponent);

Getting this error:收到此错误:

错误

step 1: create a js file that return true or false (eg util.js)步骤 1:创建一个返回truefalsejs文件(例如 util.js)

 export function when(expression, truVal, falseVal) { if (expression) { return truVal(); } if (falseVal) { return falseVal(); } return undefined; }

step 2: import util in your js file第 2 步:在您的js文件中导入 util

 import { LitElement, html } from 'lit-element'; import { when } from 'util.js'

step 3: set a isLoading property in static get properties .第 3 步:static get properties中设置isLoading属性。 So on inital load, we set onload to true in constructor所以在初始加载时,我们在constructor中将onload设置为 true

 import { LitElement, html } from 'lit-element'; import { when } from 'util.js' class EmpComponent extends LitElement { static get properties() { return { isLoading: { type: Boolean }, } } constructor() { super(); this.isLoading = true; }

step 4: once data is fetched, we are ready to render DOM.第 4 步:一旦获取数据,我们就可以渲染 DOM。 Then we can set isLoading to false and then render DOM using when然后我们可以将isLoading设置为 false,然后使用when渲染 DOM

 static get properties() { return { isLoading: { type: Boolean }, canRender: { type: Boolean } } } constructor() { super(); this.isLoading = true; this.canRender = false; this.data = this.getEmpData(); this.isLoading = false; this.canRender = true; } render() { return html ` ${when(this.isLoading,() => html`<p>Loading...</p>`)} ${when(this.canRender,() => html`<your-component></your-component>`)} ` }

This is an alternate solution for until .这是until的替代解决方案。 you can get more details from this blog sabarinath blog你可以从这个博客sabarinath blog获得更多细节

You're not returning anything in getEmpData() so this.data is undefined , hence the error.您没有在getEmpData()中返回任何内容,因此this.dataundefined ,因此会出现错误。

Keep in mind that if you add a return statement before the fetch() call this.data will then contain a Promise .请记住,如果您在fetch()调用之前添加return语句this.data将包含Promise The until directive can help in this case:在这种情况下, until指令可以提供帮助:

import {until} from 'lit-html/directives/until.js';

// ...

render() {
  return html`
    <div>
      ${until(
        this.data.then(data => data.map(emp => emp.active ? this.dataTemplate(emp) : ''),
        html`<p>Loading...</p>`,
      )} 
    </div>
  `;
}

The solution解决方案

I comment the parts where you should make changes.我评论了您应该进行更改的部分。 You don't need to do weird things with other imports你不需要对其他进口做奇怪的事情

import { LitElement, html } from 'lit-element';
    
class EmpComponent extends LitElement
{
    constructor() {
        super();
        // you were returning a promise to an Array type...
        // this.data = this.getEmpData();
        // Correct
        this.data = [];
        this.getEmpData();
    }

    // ADD PROPS
    static get properties() {
        return {
            data: {type:Array}
        };
    }

    getEmpData() {
        fetch('../../../emp-data.json')
            .then(()=>(response) {
                    if (response.status !== 200) {
                        console.log('Looks like there was a problem. Status Code: ' +
                            response.status);
                        return;
                    }
                    // SET DATA ON RESOLVE
                    response.json().then(data => this.data = data);
                }
            )
            .catch(function(err) {
                console.log('Fetch Error :-S', err);
            });
    }

    render() {
        <div>
            $ {
                (this.data || []).map(emp => emp.active ? this.dataTemplate(emp) : '')
            } 
        </div>
    }
}

customElements.define('emp-component', EmpComponent);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM