我想传递一个对象数组,然后遍历该数组并渲染每个对象。
我有以下html文件:
<stencil-component
cards = '[{"cardTitle"="placeholder", "copy"="copy1"},{"cardTitle"="placeholder2", "copy"="copy3"}]'>
</stencil-component>
在我的tsx文件中,我有以下内容:
@Prop() cards: Array<object> = [];
render(){
return (
{this.cards.map(card) => {
return (
<div>
<h1>{card.cardTitle}</h1>
<p>{card.copy}</p>
</div>
);
})}
)
}
我什至无法显示数组。我试图使用JSON.parse函数来解析数据,但这也不起作用。如果有人可以帮忙,我将不胜感激!
答案 0 :(得分:2)
HTML属性只能包含字符串,因此,如果在Stencil之外使用组件,则必须将所有属性作为字符串传递。
在Stencil(可能还有一些框架)中,您可以这样传递它:
<stencil-component
cards={[{"cardTitle":"placeholder", "copy":"copy1"},{"cardTitle":"placeholder2", "copy":"copy3"}]}>
</stencil-component>
注意:您的JSON不正确,您需要将=
替换为:
。
如果您需要使用纯HTML格式的组件,则必须手动解析 属性字符串或使用javascript进行设置。
有examples of this in the docs:
手动设置道具
import { Prop } from '@stencil/core'; export class TodoList { @Prop() myObject: object; @Prop() myArray: Array<string>; }
HTML
<todo-list></todo-list> <script> const todoListElement = document.querySelector('todo-list'); todoListElement.myObject = {}; todoListElement.myArray = []; </script>
观看道具更改
import { Prop, State, Watch } from '@stencil/core'; export class TodoList { @Prop() myObject: string; @Prop() myArray: string; @State() myInnerObject: object; @State() myInnerArray: Array<string>; componentWillLoad() { this.parseMyObjectProp(this.myObject); this.parseMyArrayProp(this.myArray); } @Watch('myObject') parseMyObjectProp(newValue: string) { if (newValue) this.myInnerObject = JSON.parse(newValue); } @Watch('myArray') parseMyArrayProp(newValue: string) { if (newValue) this.myInnerArray = JSON.parse(newValue); } }
HTML
<todo-list my-object="{}" my-array="[]"></todo-list>
答案 1 :(得分:1)
您的问题是JSON实际上不是JSON(将 = 替换为:),并且在共享数据时,数据不会自动解析为对象数组通过组件的属性。我将使用getDataFromProperty
之类的通用函数,并将其外包到另一个文件中,您可以在所有Web组件中使用它。但是,让它暂时保持简单:
@Prop() cards: Array<object> = [];
private getDataFromProperty(toParse):any{
try(JSON.parse(toParse)){
return JSON.parse(toParse);
}catch(e){
//some different conversations you wanna try e.g.
console.error('Couldnt JSON parse', e);
if(toParse.split(',').length > 0) return toParse.split(',');
}
}
render(){
if(!this.cards) this.cards = this.getDataFromProperty(this.cards);
return (
{this.cards.map(card) => {
return (
<div>
<h1>{card.cardTitle}</h1>
<p>{card.copy}</p>
</div>
);
})}
)
}
<stencil-component
cards = '[{"cardTitle": "placeholder", "copy": "copy1"},{"cardTitle": "placeholder2", "copy": "copy3"}]'>
</stencil-component>
Try and Catch将防止某些硬错误,并为您提供无法解析的情况。也许您需要针对您的需求进行微调,但是这个概念有效。在catch
条件下,您可以尝试其他一些数据对话技术。
第二,我想分享一种完全不同的方法,该方法取决于您使用的环境,但是您可以使用公共方法。比起您可以直接将数据共享到Web组件:
@Prop() cards: Array<object> = [];
@Method() setData(data){
this.cards = data;
}
render(){
//your render function as it was
}
在HTML内
<stencil-component id="web-component"></stencil-component>
<script>
let data = '[{"cardTitle": "placeholder", "copy": "copy1"},{"cardTitle": "placeholder2", "copy": "copy3"}]';
document.getElementById("web-component").setData(data);
//just call the setData function from outside works with jquery too
</script>
但是在这种方法中您需要注意一点。也许将不会调用您的render函数,因为您可以仅使用this.render();
在该函数中手动进行操作,也可以在变量前面使用@State
装饰器。