我正在尝试重写Vaadin 6应用程序(使用复杂的对话框窗口)到VaadinFusion22。初始化对话框时有问题。例如,在i18n中设置DatePicker。TestView.datePicker是在firstUpdated()上初始化的,但是TestDateDialog.datePicker总是未定义或null。
test-view.ts
@customElement('test-view')
export class TestView extends View {
@state()
private dialogOpened = false;
@query('#date1')
private datePicker?: DatePicker;
@query('#test-date')
private dialog?: TestDateDialog;
render() {
return html`<vaadin-vertical-layout class="w-full h-full" theme="padding">
<vaadin-date-picker id="date1">
</vaadin-date-picker>
<vaadin-button @click=${this.openDialog}>Open dialog</vaadin-button>
</vaadin-vertical-layout>
<test-date-dialog id="test-date" .dialogOpened="${this.dialogOpened}" @test_dialog_closed="${this.onDialogOpenedChanged}" ></test-date-dialog>
`;
}
protected firstUpdated() {
this.initDates();
}
private initDates() {
const i18n = {
today: '___TODAY___',
};
if (this.datePicker) {
this.datePicker.i18n = {
...this.datePicker.i18n,
...i18n
}
}
}
private openDialog() {
this.dialogOpened = true
if(this.dialog){
this.dialog.initDates() //1 Is this okay?
}
}
onDialogOpenedChanged(e: CustomEvent) {
this.dialogOpened = e.detail.value;
}test-date-dialog.ts
@customElement('test-date-dialog')
export class TestDateDialog extends View {
@state()
private dialogOpened = false;
@query('#date11')
private datePicker?: DatePicker;
render() {
return html`
<vaadin-dialog id="testD" no-close-on-outside-click no-close-on-esc .opened=${this.dialogOpened}
@opened-changed="${(e: CustomEvent) => this.openDialog(e.detail.value)}"
.renderer="${guard([], () => (root: HTMLElement) => {
render(html`<vaadin-vertical-layout>
<vaadin-horizontal-layout class="w-full">
<vaadin-button theme="icon tertiary contrast" @click="${() => this.cancel()}">
<vaadin-icon slot="prefix" icon="vaadin:close-big"></vaadin-icon></vaadin-button>
</vaadin-horizontal-layout>
<vaadin-date-picker id="date11">
</vaadin-date-picker>
</vaadin-vertical-layout>
`, root);
})}"></vaadin-dialog>
`;
}
private openDialog(open: boolean) {
this.dialogOpened = open;
//if (open) {
//this.initDates(); //2 Is this okay?
//}
}
//protected firstUpdated() {
// this.initDates();
//}
initDates() {
console.log(this.shadowRoot?.querySelector('#date11')) //undefined
console.log(this.querySelector('#date11')) //null
console.log(this.datePicker) //null
const i18n = {
today: '___TODAY___'
};
if (this.datePicker) {
this.datePicker.i18n = {
...this.datePicker.i18n,
...i18n
}
}
}
cancel() {
const options = {
detail: {
opened: false
},
bubbles: true,
composed: true
};
this.dispatchEvent(new CustomEvent<CancelButtonEvent>('test_dialog_closed', options));
this.dialogOpened = false;
}如何在打开对话框后(使用异步后端调用)进行初始化工作,不仅使用@property,而且还通过@query对组件进行初始化?
我在JS / TS / Lit方面没有什么经验,也许我做错了什么。
发布于 2021-12-07 16:25:22
@query装饰器不会处理由呈现器函数生成的对话框内容,因为所有的对话框内容都被传输到一个单独的覆盖元素中,该元素不是您的test-date-dialog的子元素。例如,您可以通过检查浏览器中的对话框内容来确认这一点。在这种情况下,@query装饰器不能工作,因为它只查找应用它的元素的子元素。
这里的一种解决方案可以是将对话框内容从呈现器函数中提取到单独的Lit组件(例如TestDateDialogContent)中,并在呈现器函数中呈现该组件。在TestDateDialogContent中,您可以使用@query装饰器访问日期选择器。您还可以使用常规的生命周期方法(如firstUpdated )来进行其他初始化,例如在日期选择器上设置I18N设置,或者对后端进行异步调用。
在test-date-dialog-content.ts中
@customElement('test-date-dialog-content')
class TestDialogContent extends LitElement {
@query('#date11')
private datePicker!: DatePicker;
protected firstUpdated() {
this.initDates();
}
private initDates() {
const i18n = {
today: '___TODAY___'
};
this.datePicker.i18n = {
...this.datePicker.i18n,
...i18n
};
}
render() {
return html`
<vaadin-vertical-layout>
...
<vaadin-date-picker id="date11"></vaadin-date-picker>
...
</vaadin-vertical-layout>
`;
}
}在test-date-dialog.ts中
<vaadin-dialog
.renderer="${guard([], () => (root: HTMLElement) => render(html` <test-date-dialog-content></test-date-dialog-content>`, root))}"
>
</vaadin-dialog>理想情况下,您希望尽可能避免访问单个元素(如日期选择器),而使用Lit属性绑定(<some-element .some-property="${this.someValue}">)。但是,在这种情况下,您希望用一些自定义值扩展日期选择器的I18N设置,这是不可避免的。结合将其内容传输到一个单独元素的对话框,这使得这个用例更加复杂。
https://stackoverflow.com/questions/70259112
复制相似问题