Доступ к функции класса в веб-компоненте из встроенного элемента - PullRequest
0 голосов
/ 28 декабря 2018

Я хочу выполнить определенную функцию класса из элемента внутри моего веб-компонента:

customElements.define('first-component', class FirstComponent extends HTMLElement {
    constructor() {
        super();
     }

     log() {
        console.log('Well Done!')
     }

     connectedCallback() {
        this.innerHTML = '<button onclick="log()">Do it</button>'
     }
});

Состояние прямо сейчас: ReferenceError: журнал не определен

Ответы [ 4 ]

0 голосов
/ 29 декабря 2018

С parentElement

Чтобы вызвать метод log() пользовательского элемента, у вас должна быть ссылка на него.

В вашемНапример, пользовательский элемент является родительским элементом элемента <button>, поэтому вам следует вызвать свойство parentElement кнопки, как уже указано @Smankusors:

<button onclick="this.parentElement.log()>Do it</button>

С getRootNode ()

Альтернативно, в более сложном дереве DOM, и если используется Shadow DOM, вы можете использовать getRootNode() в сочетании с host, чтобы получить ссылку на пользовательский элемент.

customElements.define('first-component', class FirstComponent extends HTMLElement {
     log() {
        console.log('Well Done!')
     }

     connectedCallback() {
        this.attachShadow({mode: 'open'})
            .innerHTML = '<button onclick="this.getRootNode().host.log()">Do it</button>'
     }
})
<first-component></first-component>

С уникальным идентификатором

Пользовательский элемент также можно вызывать с помощью его свойства id(если он есть):

customElements.define('first-component', class FirstComponent extends HTMLElement {
     log() {
        console.log('Well Done!')
     }

     connectedCallback() {
        if (!this.id)
            this.id = "_id"
        this.innerHTML = `<button onclick="${this.id}.log()">Do it</button>`
     }
})
<first-component></first-component>

С handleEvent ()

По соображениям безопасности вы можете избежать встроенного сценария и реализовать handleEvent() метод, затем вызовите внутри него определенный метод в зависимости от некоторых критериев:

customElements.define('first-component', class FirstComponent extends HTMLElement {
    log() {
        console.log('Well Done!')
    }
     
    handleEvent(ev) {
        if (ev.target.innerText == 'Do it')
            this.log()
    }

    connectedCallback() {
        this.innerHTML = '<button>Do it</button>'
        this.addEventListener('click', this)
    }
})
<first-component></first-component>
0 голосов
/ 28 декабря 2018

Поскольку DOM и его элементы не знают области, в которой он живет, просто установка значения innerHTML не сработает, поскольку log не существует в window, который является областью DOM.Следовательно, лучше всего создать элемент и добавить его в Shadow Dom пользовательского элемента и одновременно добавить eventListener к кнопке.

customElements.define('first-component', class FirstComponent extends HTMLElement {
    constructor() {
        super();
     }

     log() {
        console.log('Well Done!')
     }

     connectedCallback() { // This parentheses was also missing
         var shadow = this.attachShadow({mode: 'open'});
         const button = document.createElement("button");
         button.textContent = 'Do it!';
         button.addEventListener('click', () => this.log());
         shadow.appendChild(button);
     }
});
<first-component id="component"></first-component>
0 голосов
/ 28 декабря 2018

Вы должны - по многим причинам - прекратить использовать встроенные прослушиватели событий .Вместо этого используйте addEventListener - в этом случае в connectedCallback.

customElements.define('first-element', class FirstElement extends HTMLElement {
    constructor() {
        super();
     }

     log() {
        console.log('Well Done!')
     }

     connectedCallback() {
        const btn = document.createElement('button');
        btn.textContent = 'Do it!';
        btn.type = 'button'; // otherwise it's type=submit
        btn.addEventListener('click', this.log);
        this.appendChild(btn);
     }
});
<first-element></first-element>
0 голосов
/ 28 декабря 2018

Это не должно быть log(), но this.log(), потому что эта область действия log является только этим элементом, а не в области действия window, поэтому ваш код должен быть

customElements.define('first-component', class FirstComponent extends HTMLElement {
    constructor() {
        super();
     }

     log() {
        console.log('Well Done!')
     }

     connectedCallback()
        this.innerHTML = '<button onclick="this.parentElement.log()">Do it</button>'
     }
});

- РЕДАКТИРОВАТЬ - Извините, моя ошибка, я только что увидел, что вы добавили кнопку внутри пользовательского элемента, ну ... Это должно быть this.parentElement.log(), если вы все еще хотите предпочесть inline

...