Атрибут не изменяется внутри ShadowDOM - PullRequest
0 голосов
/ 24 апреля 2020

В моем следующем коде изменение значения не обновляет входное значение: Почему?

class textfield extends HTMLElement {

    get value()
    {
        return this.getAttribute("value");
    }

    set value(val)
    {
        this.setAttribute('value', val);
    }

    get readonly() {
        return this.hasAttribute("readonly");
    }

    set readonly(val)
    {
        if (val)
        {
            this.setAttribute("readonly", '');
        }
        else
        {
            this.removeAttribute("readonly");
        }
    }

    static get observedAttributes() {
        return ['readonly', 'value'];
    }

    attributeChangedCallback(name, oldValue, newValue) {
        console.log(name, newValue) ;
    }

    constructor()
    {
        super();
        this.attachShadow({ "mode": "open" });
    }

    connectedCallback()
    {
        this.shadowRoot.innerHTML =  
        /*html*/`
        <div>
            <div>
                Lable
            </div>
            <div>
                <input id="vi-input" type="text" value="${this.getAttribute("value")}" ${ this.hasAttribute("readonly") ? "readonly" : "" } />
            </div>
            <div>
                <span>Error</span>
            </div>
        </div>
        `;
    }
}

window.customElements.define("vi-textfield", textfield);

И в моем индексе. html:

.... 
        <vi-textfield id="myInput" value="2" validation="^\d{4}$" ></vi-textfield>
....

Когда я обновляю это по JS, скажем по:

document.getElementById("myInput").value = 3;

будет указан файл console.log для attributeChangedCallback, но само значение не изменится ...

Ответы [ 2 ]

3 голосов
/ 24 апреля 2020

Ваш input не обновляется, потому что это 2 разных элемента.

 set value(val) {
   this.setAttribute('value', val);
 }

устанавливает атрибут value на

<vi-textfield value="[val]">

не атрибут value в

<input id="vi-input" type="text" value="${this.getAttribute("value")}"/>

, который является другим элементом в ваших элементах shadowDOM

value="${this.getAttribute("value")}" выполняется один раз , потому что connectedCallback() работает один раз

Если вы хотите установить оба , вы можете сделать:

 set value(val) {
   this.setAttribute('value', val);
   this.shadowRoot.getElementById("vi-input").setAttribute("value", val);
 }

Если вы хотите их в syn c, вам также нужно установить setAttribute код, когда value на входе изменяется.

PS.

set readonly(val) {
        if (val) {
            this.setAttribute("readonly", '');
        } else {
            this.removeAttribute("readonly");
        }
    }

можно записать как:

set readonly(val) {
        this.toggleAttribute("readonly", val);
}
0 голосов
/ 24 апреля 2020

Полагаю, вы устанавливаете значение, но ничего не делаете после этого, по крайней мере, не в поле ввода. Ваш элемент vi-textfield фактически обновляется, если вы просматриваете вкладку своих элементов с помощью инструментов разработчика вашего браузера. Вы можете восстановить html, например, после установки значения, вызвав

this.connectedCallback();

, чтобы убедиться, что поле ввода также содержит обновленное значение.
Или вам нужно найти способ выбрать и обновить поле ввода отдельно. Или просто вспомните метод connectedCallback(), как я упоминал.

Или вы можете добавить какой-нибудь MutationObserver в ваш класс (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver), но я не думаю, что это должно работать из коробки то, что вы могли подумать: обновляя значение хоста, обновляйте теневые элементы.

...