【发布时间】:2021-06-09 14:19:12
【问题描述】:
我有 2 个组件 - product-overview 和 product-overview-item。 product-overview-item 是一个单独的项目,每当内置的 render() 方法在屏幕上加载 HTML 模板时,它就会在 product-overview 组件内部呈现。
我有一个带有 HATEOAS 链接数组的对象(例如,agreement),如下所示。
{
"id": "1"
"type": "INVEST"
"group": "INVEST"
"role": "HOLD"
"accountId": "1",
"commercialId": {
"value": "DEFAULT",
"type": "3000",
},
"productName": "Self Invest",
"displayAlias": "Superman",
"visible": true,
"status": "ACTIVE"
"balance": {
"currency": "EUR",
"value": "34.00",
},
"_links": [
{
"rel": "details",
"href": "/nl/agree/192712812/investbalance",
},
{
"rel": "portfolio",
"href": "/dv/agreesecurities/981261892y9aksjakcnm",
},
{
"rel": "edit",
"href": "/mb/port/921nclaskofknsscsdwd",
}
]
}
我需要对以 /nl/agreement 开头并以 /investmentbalance 结尾的 HATEOAS 链接数组中的 href 值进行 API 调用。投资余额的反应与上述反应非常相似。由此,我需要获取 balance 对象并将其传递给子组件(product-overview-item)。
balance 对象与上图类似。这是我迄今为止尝试过的。
1. product-overview.js(父组件)
_getUrl(agreement) {
const { _links } = agreement;
const nlAgreements = _links?.filter(link => link?.rel && link?.rel === 'details' && link?.href && link?.href.startsWith('/nl/agreements'));
if (nlAgreements === undefined || nlAgreements.length === 0) return;
return nlAgreements[0]?.href;
}
async _fetchMigratedInvestmentBalance(agreement) {
await ajax.get(this._getUrl(agreement))
.then(response => {
if (!response) throw new Error('Failed to fetch balance');
else return response;
})
.then(response => this.investmentBalance = response?.data?.balance)
.catch(error => {
throw new Error('Failed to fetch balance due to: ', error);
});
}
_getProducts(status, role, tab) {
...
...
if (this.agreementsList && this.agreementsList.length > 0) {
let groupedAgreements = [];
const filteredAgreements = this._filterAgreements(this.agreementsList, status, role);
groupedAgreements = this._getGroupedAgreements(filteredAgreements);
tab.count = filteredAgreements.length;
if (groupedAgreements && groupedAgreements.length > 0) {
const noBalanceAlert = this.isAPA ? html`
<div class="alert"><uic-alert type="error">
${localize.msg('product-overview:NO_BALANCE')}
</uic-alert></div>
` : '';
return html`
${noBalanceAlert}
${groupedAgreements.map(item => html`
<uic-expandable-item>
...
<article slot="details" class="item-details productDetails">
<ul class="list-unstyled">
${item.agreements.map((agreement, index) => html`
<li class="productDetailsItem">
${when(BeProductOverviewServices._isClickable((agreement.type).toUpperCase()), () => html` <a @click='${e => this._clickedToProductDetailsPage(e, item.agreements)}'
data-group="${item.agreementType}" data-index="${index}"
data-url="product-details/be/${item.agreementType}/${agreement.commercialId.value}">
<product-overview-item .agreement="${agreement}" @connected="${this._fetchMigratedInvestmentBalance(agreement)}" .balance="${this.investmentBalance}" .role="${role}">
</product-overview-item></a>`, () => html`<product-overview-item
.agreement="${agreement}" @connected="${this._fetchMigratedInvestmentBalance(agreement)}" .balance="${this.investmentBalance}" .role="${role}"
.disabled="${this.disabled}"></product-overview-item>
`)}
<li>
`)}
</ul>
</article>
</uic-expandable-item>`)}`;
`)}`;
}
}
return html``;
}
_getProducts() 函数在 render() 函数中被调用。
2。 product-overview-item.js(子组件)
在子组件中,每次在connectedCallback() 函数中加载项目时,我都会调度一个事件。
class beProductOverviewItem extends LitElement {
static get properties() {
return {
agreement: { type: Object },
balance: { type: Object, attribute: 'investment-balance', reflect: true },
role: { type: String },
disabled: { type: Boolean },
};
}
static get styles() {
return beProductOverviewStyle;
}
connectedCallback() {
super.connectedCallback();
this.dispatchEvent(new CustomEvent('connected'));
}
render() {
return html`<uic-item ?disabled="${this.disabled}">
<uic-item-header>
<span class="bold">${this.agreement?.productName}</span>
<span class="bold" slot="header-addon">
${(this.agreement?.status === 'CLOSED') ? html`
${localize.msg('product-overview:CLOSED')}` : (this.agreement?.type !== 'INVESTMENT' && this.agreement?.balance) ? html`
${formatAmountHtml(this.agreement?.balance?.value, {
locale: localize.locale,
style: 'currency',
currencyDisplay: 'symbol',
currency: this.agreement?.balance?.currency,
})}
` : (this.agreement?.type === 'INVESTMENT' && this.balance) ? html`
${formatAmountHtml(this.balance?.value, {
locale: localize.locale,
style: 'currency',
currencyDisplay: 'symbol',
currency: this.balance?.currency,
})}
` : ''}
</uic-item>`;
}
}
promise 在没有 undefined/pending 的情况下解析,但这次它进入了一个无限循环,不断地加载余额。有什么我们遗漏的吗?
注意:现在,我将首先声明我没有足够的经验来理解这些异步调用发生了什么。如何将 async/await 逻辑合并到我的组件中?
【问题讨论】:
-
大多数 Lit-heads 在 Slack 频道中闲逛 Lit and Friends
-
@Danny'365CSI'Engelman - 你能在这里提出答案吗?
-
对不起,我不是 Lit 用户...我是 vanilla JS Web Components 的朋友
标签: javascript web-component lit-element lit-html native-web-component