Как я могу импортировать экспортированные из модуля функции в глобальную область видимости для обработчиков событий HTML onclick = ""? - PullRequest
0 голосов
/ 21 февраля 2019

Простая HTML-страница с использованием SystemJS 0.21, которая загружает модуль JavaScript, скомпилированный из TypeScript.Веб-страница HTML имеет обработчик событий onclick="" в стиле, который вызывает функцию, объявленную в файле модуля:

tsconfig.json

{
    "compilerOptions": {
        "module": "system",
        "moduleResolution": "node"
    }
}

Page.ts

export function onButtonClick( e: Event, btn: HTMLButtonElement ): boolean {

    console.log( 'clicked!' );
    return true;
}

Я использую SystemJS на HTML-странице веб-сайта (не SPA), например:

system.config.js

System.config( {

    map: { /* ... */ },

    packages: {
        '/scripts/': { defaultExtension: 'js' }
    }

} );

System.import( '/scripts/Page' );

Page.html

<html>
<head>
    <script src="/scripts/system.src.js"></script>
    <script src="/scripts/system.config.js"></script>
</head>
<body>

    <button onclick="onButtonClick( event, this )">Click me and check the browser console</button>

</body>
</html>

Это не работает, потому что функция onButtonClick определена в Page.js как функция внутри модуля, что означает, что она не импортируется как свойство в глобальный (Window) объект всценарии потребленияТаким образом, я получаю вывод в окне консоли:

Uncaught ReferenceError: onButtonClick не определено в HTMLButtonElement.onclick (Page.html: 8)

Так как же мне заставить <button onclick="onButtonClick( event, this )" использовать function onButtonClick в Page.ts / Page.js?

1 Ответ

0 голосов
/ 22 февраля 2019

Я разработал обходное решение на данный момент:

  1. Расширьте глобальный Window интерфейс объекта в модуле TypeScript для добавления новых глобальных функций.
  2. Назначьте эти объявленные свойства функциина window внутри функции модуля «верхнего уровня».

Это не то же самое, что SystemJS импортирует модуль в объект window (которыйэто то, что я изначально хотел), и этот подход также требует, чтобы я изменил модуль, который я импортирую, но пока он работает.

Вот так:

Page.ts

declare global {
    declare interface Window {
        onButtonClick( e: Event, btn: HTMLButtonElement ): boolean;
    }
}

function onButtonClick( e: Event, btn: HTMLButtonElement ): boolean {

    console.log( 'clicked!' );
    return true;
}

window.onButtonClick = onButtonClick;

Функцию onButtonClick больше не нужно экспортировать.И это можно сделать еще более кратким, просто назначив функцию напрямую:

Page.ts

declare global {
    declare interface Window {
        onButtonClick( e: Event, btn: HTMLButtonElement ): boolean;
    }
}

window.onButtonClick = onButtonClick( e: Event, btn: HTMLButtonElement ): boolean {

    console.log( 'clicked!' );
    return true;
};

Поскольку модуль Page.ts / Page.js загружается асинхронно, это означает, чтокогда Page.html загружает, атрибуты onclick="" не будут работать до тех пор, пока модуль не будет загружен, но при условии, что это произойдет быстро после загрузки страницы, проблем с пользовательским интерфейсом не возникнет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...