渲染函数中的模板未解析 - LitElement
Template inside render function is not resolving - LitElement
我试图通过 ajax 调用获取列表,但在它被解析之前,render()
方法被调用并且模板片段依赖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);
出现此错误:
您没有在 getEmpData()
中返回任何内容,因此 this.data
是 undefined
,因此出现错误。
请记住,如果您在 fetch()
调用之前添加 return
语句,则 this.data
将包含 Promise
。 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>
`;
}
第 1 步: 创建一个 js
文件 return true
或 false
(例如 util.js )
export function when(expression, truVal, falseVal) {
if (expression) {
return truVal();
}
if (falseVal) {
return falseVal();
}
return undefined;
}
第 2 步: 在您的 js
文件中导入实用程序
import {
LitElement,
html
} from 'lit-element';
import {
when
} from 'util.js'
步骤 3: 在 static get properties
中设置一个 isLoading
属性。所以在初始加载时,我们在 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;
}
第 4 步: 获取数据后,我们就可以渲染 DOM。然后我们可以将 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>`)}
`
}
这是 until
的替代解决方案。您可以从这个博客中获得更多详细信息 sabarinath blog
解决方案
我评论了您应该更改的部分。你不需要对其他导入做奇怪的事情
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);
我试图通过 ajax 调用获取列表,但在它被解析之前,render()
方法被调用并且模板片段依赖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);
出现此错误:
您没有在 getEmpData()
中返回任何内容,因此 this.data
是 undefined
,因此出现错误。
请记住,如果您在 fetch()
调用之前添加 return
语句,则 this.data
将包含 Promise
。 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>
`;
}
第 1 步: 创建一个 js
文件 return true
或 false
(例如 util.js )
export function when(expression, truVal, falseVal) {
if (expression) {
return truVal();
}
if (falseVal) {
return falseVal();
}
return undefined;
}
第 2 步: 在您的 js
文件中导入实用程序
import {
LitElement,
html
} from 'lit-element';
import {
when
} from 'util.js'
步骤 3: 在 static get properties
中设置一个 isLoading
属性。所以在初始加载时,我们在 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;
}
第 4 步: 获取数据后,我们就可以渲染 DOM。然后我们可以将 isLoading
设置为 false,然后使用 when
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>`)}
`
}
这是 until
的替代解决方案。您可以从这个博客中获得更多详细信息 sabarinath blog
解决方案
我评论了您应该更改的部分。你不需要对其他导入做奇怪的事情
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);