Запуск событий из тонкого компонента и прослушивание его из содержащей страницы

В моем компоненте есть этот код, который по сути совпадает с примером в svelte docs:

export default {
  methods: {
    assessmentMouseover(e) {
      const event = new CustomEvent('assessment-mouseover', {
        detail: 'something',
        bubbles: true,
        cancelable: true,
        composed: true, // makes the event jump shadow DOM boundary
      })
      this.dispatchEvent(event)
    },
  },
  ...
}

Затем у меня есть этот код в теге script на HTML-странице, который создает этот компонент, который также по сути такой же, как и svelte docs:

const el = document.querySelector('#radar')
el.addEventListener('assessment-mouseover', event => {
  console.log('got here')
})

Однако, когда я инициирую событие, я получаю эту ошибку: this.dispatchEvent is not a function.

Я пробовал несколько вариантов this.dispatchEvent(), например, просто dispatchEvent(), который не вызывает ошибок, но также не запускает слушателя; и window.dispatchEvent(), который также не запускается.

Что я делаю неправильно?


person Larry Maccherone    schedule 28.11.2018    source источник
comment
Эти документы взяты из раздела Custom Elements - компилируете ли вы свои компоненты как пользовательские элементы? Если нет, вам следует использовать this.fire. (Этот интерфейс будет унифицирован в v3.)   -  person Rich Harris    schedule 28.11.2018
comment
Я так думаю. Я начал с шаблона компонента, и вот как мы его используем. Компилируем компонент в svelte. Затем он потребляется из приложения React.   -  person Larry Maccherone    schedule 28.11.2018
comment
Можете ли вы создать репродукцию? Похоже, что-то не так!   -  person Rich Harris    schedule 29.11.2018
comment
Приведенное ниже решение Брайса сработало, поэтому мне не нужно воспроизводить. Думаю, теперь у меня единственный вопрос: обязан ли я отправить запрос на перенос, исправляющий документацию, чтобы она соответствовала решению Брайса. Ключом к тому, чтобы это заработало, было привязать событие к document.   -  person Larry Maccherone    schedule 30.11.2018
comment
Я не думаю, что это решение само по себе - оно работает, только если кто-то прикрепляет слушателя к документу. Идея CustomEvent состоит в том, что вы можете отправить его из определенного элемента, а заинтересованные стороны могут прослушивать событие в этом элементе (или его родителях, если оно всплывает). Если есть ошибка, то она в самом Svelte, а не в документации, но мы не можем знать, есть она или нет, без репро.   -  person Rich Harris    schedule 30.11.2018
comment
Я согласен с комментарием Rich, поэтому я сделал Repl, относящийся к элементу. this.dispatchEvent (событие) не отправляется, а нацелен на конкретный тег HTML, к которому прикреплено событие, работает: svelte.technology/   -  person Brice    schedule 30.11.2018


Ответы (1)


Ответ рабочего случая: https://svelte.technology/repl?version=2.15.3&gist=7b0b820ce452cf6d5d10ebf456627651

Test.html:

<button id="{id}" on:mouseover="doMouseOver(event)">
    {isOver}
</button>

<script>
    export default {
        data() {
            return {
                isOver: 'Over Me!'
            }
        },

        methods: {
            doMouseOver(e) {
                const event = new CustomEvent('assessment-mouseover', {
                    detail: Math.random(),
                    bubbles: true,
                    cancelable: true,
                    composed: true, // makes the event jump shadow DOM boundary
                })

                //this.dispatchEvent(event)

                let source = e.target || e.srcElement
                source.dispatchEvent(event)
            }
        }
    }
</script>

App.html:

<h1>From Test: {text}</h1>

<Test id="radar"/>


<script>
    export default {
        components: {
            Test: './Test.html'
        },

        data() {
            return {
                text: 'Wait for over'
            }
        },

        oncreate() {
            const el = document.querySelector('#radar')
            el.addEventListener('assessment-mouseover', event => {
                this.set({text: event.detail})
            })
        },
    }
</script>
person Brice    schedule 28.11.2018
comment
Это сработало! Спасибо!!! Ключевое отличие состоит в том, что событие находится на document, а не на элементе. - person Larry Maccherone; 28.11.2018
comment
Хорошо, поэтому я обновил свой код, чтобы он соответствовал последним изменениям этого ответа (больше не прикрепляю событие к документу). Лучше прикрепить к элементу, но он все равно не соответствует документации. Три возможности: 1) ошибка в svelte, 2) неправильная документация или 3) неполная документация, потому что она будет работать в разных контекстах. Я просто не знаю достаточно, чтобы понять, что это такое. Кто-нибудь из вас? - person Larry Maccherone; 03.12.2018