0
votes

Le modèle à l'intérieur de la fonction de rendu ne se résout pas - LitElement

J'essayais d'obtenir une liste via un appel ajax mais avant qu'elle ne soit résolue, la méthode render() est appelée et le fragment de modèle dépendant de la promesse était impossible de résoudre et jette undefined.

Question : Comment afficher un chargeur jusqu'à ce que j'obtienne les données de la promesse?

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);

Obtention de cette erreur:

 Erreur


0 commentaires

3 Réponses :


1
votes

Vous ne renvoyez rien dans getEmpData () donc this.data est indéfini , d'où l'erreur.

Gardez dans sachez que si vous ajoutez une instruction return avant l'appel fetch () , this.data contiendra alors une Promise . La directive jusqu'à peut vous aider dans ce cas:

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>
  `;
}


0 commentaires

2
votes

étape 1: créez un fichier js qui renvoie true ou false (par exemple util.js)

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>`)}
  `
}

étape 2: importez l'utilitaire dans votre fichier js

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;
    }

étape 3: définissez une propriété isLoading dans static get properties . Ainsi, lors du chargement initial, nous définissons onload sur true dans constructor

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

étape 4: une fois les données récupérées, nous sommes prêts à rendre le DOM. Ensuite, nous pouvons définir isLoading sur false, puis afficher le DOM en utilisant when

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

Ceci est une solution alternative pour jusqu'à . vous pouvez obtenir plus de détails sur ce blog blog sabarinath


0 commentaires

1
votes

La solution

Je commente les parties où vous devez apporter des modifications. Vous n'avez pas besoin de faire des choses bizarres avec d'autres importations

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);


0 commentaires