简体   繁体   中英

Lit-element - Importing a component inside another component and then accessing the DOM of the imported component

I've honestly racked my brain on this for a couple days. I'm decently new to lit-element and web components in general.

Basically, I'm building a new component called <date-picker> and it uses the Flatpickr plugin. This Date Picker component imports another component called <textfield> . Inside of that component there is a wrapper(.date-picker) with an input field and an icon. I need to be able to access the wrapper so I can click the input field and icon to trigger the calendar popup. But no matter what I do, I can't reach those the dom elements inside the component. I've tried accessing them using this.shadowRoot.querySelector('.date-picker') along with the light dom document.querySelector('.date-picker') among a variety of other things. Sample code below. I appreciate any insight you can offer.

Date picker component:

render() {
  return html`
    <textfield iconalt="Calendar" iconname="calendar" label="Calendar" optionaltext="hide"></textfield>
  `;
}

updated() {
  var datePickerShadow = this.shadowRoot.querySelector('.date-picker'); // gets el in shadow dom
  var datePickerLight = document.querySelector('.date-picker'); // gets el in light dom

  var importantDate = [Date.parse('2021-1-27'), Date.parse('2021-1-5'), Date.parse('2021-2-9')];
    var datePicker = flatpickr(datePickerLight, {
        wrap: true,
        disable: ["2021-01-30", "2021-01-21", "2021-01-08", new Date(2025, 4, 9) ],
        allowInput: true,
        clickOpens: false,
    })
}

If <textfield> is a custom element then its tagname is illegal: custom element tags must contain at least a - . This is probably preventing the browser from upgrading it (and thus rendering its content and executing its logic).

Anyway if .date-picker is inside of <textfield> 's template, neither of the querySelector calls you tried would work: the first selects inside <date-picker> 's shadow dom but does not recurse in child components, while the second completely misses shadow doms.

What you can do is:

  • Use cascaded querySelectors

    class DatePicker extends LitElement { async firstUpdated() { const textField = this.renderRoot.querySelector('text-field'); await textField.updated; // Wait for first render of text-field const datePicker = textField.renderRoot.querySelector('.date-picker'); } }
  • Move .date-picker in <date-picker> 's template if possible

  • Pass .date-picker to <text-field> which renders it in a slot

    // This way you can directly select.date-picker render() { return html` <text-field> <div class="date-picker"></div> </text-field> `; }
  • Instantiate the picker inside <text-field> and expose the instance using a property (or part of its functionality through methods and properties).

(I'd avoid the first option if possible)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM