首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在vaadin-对话框中初始化组件

如何在vaadin-对话框中初始化组件
EN

Stack Overflow用户
提问于 2021-12-07 11:11:10
回答 1查看 319关注 0票数 1

我正在尝试重写Vaadin 6应用程序(使用复杂的对话框窗口)到VaadinFusion22。初始化对话框时有问题。例如,在i18n中设置DatePicker。TestView.datePicker是在firstUpdated()上初始化的,但是TestDateDialog.datePicker总是未定义或null。

test-view.ts

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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方面没有什么经验,也许我做错了什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-07 16:25:22

@query装饰器不会处理由呈现器函数生成的对话框内容,因为所有的对话框内容都被传输到一个单独的覆盖元素中,该元素不是您的test-date-dialog的子元素。例如,您可以通过检查浏览器中的对话框内容来确认这一点。在这种情况下,@query装饰器不能工作,因为它只查找应用它的元素的子元素。

这里的一种解决方案可以是将对话框内容从呈现器函数中提取到单独的Lit组件(例如TestDateDialogContent)中,并在呈现器函数中呈现该组件。在TestDateDialogContent中,您可以使用@query装饰器访问日期选择器。您还可以使用常规的生命周期方法(如firstUpdated )来进行其他初始化,例如在日期选择器上设置I18N设置,或者对后端进行异步调用。

test-date-dialog-content.ts

代码语言:javascript
复制
@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

代码语言:javascript
复制
<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设置,这是不可避免的。结合将其内容传输到一个单独元素的对话框,这使得这个用例更加复杂。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70259112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档