2017-01-27 2 views
1

Я столкнулся с крахом в своем веб-приложении на Safari, потому что определение типа для функции относится к интерфейсу TouchEvent. Эта переменная издавалась дословно в метаданных декоратора в скомпилированном JS и is not implemented in desktop Safari.Typcript + Angular 2: Как я могу гарантировать, что метаданные метаданных, обработчиками которых будут ссылаться на переменные в области видимости, чтобы избежать «неопределенной» ошибки?

Этот конкретный случай был легко решить (вместо этого я использовал только Event), но это оставило меня в недоумении ... есть ли там какие-либо другие метаданные-декораторы в моем приложении, разбивающиеся на некоторые браузеры, которые я не тестировал?

Вот пример Угловое 2 директива, которая иллюстрирует проблему:

import { Directive, HostListener } from '@angular/core'; 

@Directive({ 
    selector: '[touchTest]' 
}) 
export class TouchTest { 
    constructor() { } 

    @HostListener('touchend', ['$event']) onTouchend(event: TouchEvent) { 
     console.log(event); 
    } 
} 

Если вы собираете это с tsc touch-test.ts --emitDecoratorMetadata --experimentalDecorators, выход включает в себя (полный выход JS here) это:

__decorate([ 
    core_1.HostListener('touchend', ['$event']), 
    __metadata("design:type", Function), 
    __metadata("design:paramtypes", [TouchEvent]), 
    __metadata("design:returntype", void 0) 
], TouchTest.prototype, "onTouchend"); 

Что касается TouchEvent throws TouchEvent is not defined на Safari.

Я заметил, что некоторые другие типы параметров (те, которые я явно импортировал?) Испускаются просто как Object в результате JS, который гарантированно будет в безопасности. Я также вижу, что interface TouchEvent определен в нескольких файлах .d.ts в модуле npm typescript, поэтому я смог использовать его без ошибок при компиляции.

Есть ли общее правило для предотвращения подобных проблем? В моей среде может быть какая-то проблематичная настройка (я начал с angular2-webpack-starter), но просматривая tsconfig.json и другие, возможно, соответствующие файлы конфигурации, ничто не выскочило на меня.

ответ

1

Файлы lib.d.ts просто используют последний веб-сайт и мало заботятся о старших и отсутствующих браузерах. И они не должны. Это зависит от вас, чтобы проверить, доступен ли встроенный класс/объект в браузерах, которым вы хотите оказать поддержку. Если это не так, вы можете использовать полисы или найти другой путь вокруг него или отказаться от поддержки этих браузеров (я предлагаю последнее: не нужно останавливаться в прошлом или поддерживать браузеры, которые отказываются соответствовать последним стандартам)

+0

Увы, это не о старых браузерах! [Ни последняя версия Edge, ни новейшая версия Safari для настольных компьютеров вообще не поддерживаются] (http://caniuse.com/#feat=touch), поэтому мое приложение будет ломаться для слишком большого количества пользователей. Я думаю, у меня нет выбора, кроме как вручную проверить все предположительно глобальные интерфейсы, используемые в аннотациях типа в моем приложении, и подтвердить, что они действительно хорошо поддерживаются. Это большая боль. – tobek

+0

Вот что я имел в виду с браузерами, которые отказываются соблюдать. Safari является одним из таких, как opera – PierreDuc

+0

Конечно, и я в последнее время все больше разочарован Safari здесь, но не поддерживает пользователей, которые используют Edge или Safari, в большинстве случаев это не практическое решение. Что делать, если я работаю на веб-сайте банка или правительства? В идеале TypeScript может помочь здесь вместо того, чтобы замолчать возможные ошибки времени выполнения. Я задал более прямой вопрос об этом здесь: http://stackoverflow.com/questions/41916890/is-there-a-more-cross-browser-safe-version-of-lib-dom-d-ts- and-other-default-amb – tobek

0

Другой вариант - использовать hammer.js.

+0

Речь идет не об использовании сенсорных событий, а именно о том, что появилось в этом случае. Проблема состоит в том, что машинопись выводит ссылки на глобальные переменные, которые не имеют гарантии для определения. – tobek

Смежные вопросы