Использование мобильных событий в Angular2
мне было интересно, могу ли я получить некоторую помощь в отношении событий для мобильных устройств. Я искал способ привязки функций к событиям салфетки в Angular 2. Я видел в этом этот вопрос на Github, который упоминает, что Angular 2 использует молоток.js для мобильной обработки событий.
у меня возникли проблемы с получением события для работы, потому что я получаю следующую ошибку:
исключение: молоток.js не загружен, не может связать swipeleft событие
ниже приведен фрагмент моего кода:
import {Component, View, AfterContentInit} from 'angular2/core';
import {HelperService} from "./helper-service";
import {HammerGesturesPluginCommon} from 'angular2/src/platform/dom/events/hammer_common'
@View({
template: `<div [id]="middleCircle" (swipeleft)="doThis()"></div>`
})
export class ColumnDirective implements AfterContentInit {
constructor(private helperService:HelperService) {}
doThis(){
console.log('This thing has been done.');
}
}
Если я добавлю жесты молотка в свой конструктор, я получу эту ошибку:
constructor(private helperService:HelperService, private hammerGesturesPluginCommon: HammerGesturesPluginCommon) {}
исключение: нет поставщика для t! (ColumnDirective - > t)
любая помощь в этом вопросе будет оценена!
6 ответов
после долгих махинаций, я не HammerGesturesPluginCommon Angular2 на работу (до сих пор). Вдохновленный ответом Билла Мэйса, я представляю это как разработку его ответа, который я смог получить (протестирован на Ipad mini и телефоне Android).
в основном, мое решение заключается в следующем.
во-первых, вручную эталонного молотка.js в тегах скрипта вашего индекса.html-файл (я также ссылаюсь на hammer-time для устранения 300ms задержка):
во-вторых, установите определения типов для hammerjs (tsd install hammerjs-save). Затем вы можете создать директиву Angular2 attibute следующим образом:
/// <reference path="./../../../typings/hammerjs/hammerjs.d.ts" />
import {Directive, ElementRef, AfterViewInit, Output, EventEmitter} from 'angular2/core';
@Directive({
selector: '[hammer-gestures]'
})
export class HammerGesturesDirective implements AfterViewInit {
@Output() onGesture = new EventEmitter();
static hammerInitialized = false;
constructor(private el: ElementRef) {
}
ngAfterViewInit() {
if (!HammerGesturesDirective.hammerInitialized) {
let hammertime = new Hammer(this.el.nativeElement);
hammertime.get('swipe').set({ direction: Hammer.DIRECTION_ALL });
hammertime.on("swipeup", (ev) => {
this.onGesture.emit("swipeup");
});
hammertime.on("swipedown", (ev) => {
this.onGesture.emit("swipedown");
});
hammertime.on("swipeleft", (ev) => {
this.onGesture.emit("swipeleft");
});
hammertime.on("swiperight", (ev) => {
this.onGesture.emit("swiperight");
});
hammertime.on("tap", (ev) => {
this.onGesture.emit("tap");
});
HammerGesturesDirective.hammerInitialized = true;
}
}
}
необходимо указать молоток.DIRECTION_ALL если вы хотите обнаружить вертикальные (вверх/вниз) свайпы (левые/правые свайпы по умолчанию, а не вертикальные). Дополнительные параметры api hammer можно найти здесь:http://hammerjs.github.io/api/#hammer
наконец, в вашем Родительском компоненте вы можете сделать что-то вроде этого:
import {Component} from "angular2/core";
import {HammerGesturesDirective} from "./path/HammerGesturesDirective";
@Component({
selector: "my-ng2-component",
template: `<div style='width:100px; height: 100px;background-color: red'
(onGesture)="doSwipe($event)" hammer-gestures></div>`,
directives: [HammerGesturesDirective]
})
export class MyNg2Component {
constructor() { }
doSwipe(direction: string) {
alert(direction);
}
}
таким образом, вам нужно только ссылаться на атрибут молоток-жесты когда вы хотите включить жесты молота на любом конкретном элементе. Примечание: элемент, кажется, нужен уникальный ID для работы.
ну, долго после операции, но если у вас есть только простые требования и не хотите гадить с молотком.Джей-Эс, вот базовый горизонтальный свайпер. Просто зайдите в компонент и добавьте свой собственный doSwipeLeft
и doSwipeRight
функции.
touch1 = {x:0,y:0,time:0};
@HostListener('touchstart', ['$event'])
@HostListener('touchend', ['$event'])
//@HostListener('touchmove', ['$event'])
@HostListener('touchcancel', ['$event'])
handleTouch(ev){
var touch = ev.touches[0] || ev.changedTouches[0];
if (ev.type === 'touchstart'){
this.touch1.x = touch.pageX;
this.touch1.y = touch.pageY;
this.touch1.time = ev.timeStamp;
} else if (ev.type === 'touchend'){
var dx = touch.pageX - this.touch1.x;
var dy = touch.pageY - this.touch1.y;
var dt = ev.timeStamp - this.touch1.time;
if (dt < 500){
// swipe lasted less than 500 ms
if (Math.abs(dx) > 60){
// delta x is at least 60 pixels
if (dx > 0){
this.doSwipeLeft(ev);
} else {
this.doSwipeRight(ev);
}
}
}
}
}
Я немного колебался, чтобы добавить жесты салфетки в мое приложение, потому что ответы здесь, казалось, предполагали, что это будет немного грязно.
исключение: молоток.js не загружен, не может связать событие swipeleft
эта ошибка легко справляется с помощью просто загрузки молотка.js. Нет необходимости в пользовательском коде.
другая ошибка, упомянутая в комментариях, кажется, была ошибкой, которая исправлена с rc1.
я смог заставить что-то работать, обойдя встроенную интеграцию Hammer и запустив свой собственный:
import { Component, ElementRef, AfterViewInit } from 'angular2/core';
@Component({
selector: 'redeem',
templateUrl: './redeem/components/redeem.html'
})
export class RedeemCmp implements AfterViewInit {
static hammerInitialized = false;
constructor(private el:ElementRef) { }
ngAfterViewInit() {
console.log('in ngAfterViewInit');
if (!RedeemCmp.hammerInitialized) {
console.log('hammer not initialised');
var myElement = document.getElementById('redeemwrap');
var hammertime = new Hammer(myElement);
hammertime.on('swiperight', function(ev) {
console.log('caught swipe right');
console.log(ev);
});
RedeemCmp.hammerInitialized = true;
} else {
console.log('hammer already initialised');
}
}
}
"исключение: молоток.js не загружается, не может связать событие swipeleft " возникает, потому что hammerjs должен быть включен в страницу.
пример:
Я прочитал все другие ответы о том, как использовать hammerjs с угловым, и они выглядят хакерскими. По умолчанию HammerJs отключил методы SwipeDown и SwipeUp. Все предыдущие ответы не верны angular2 typescript способ решения проблемы жестов или переопределения по умолчанию настройки молотка. Мне потребовалось около 4 часов копания в angular2 и hammerjs.
вы тут:
Первое, что нам понадобится, это hammerjs typings для angular2.
typings install github:DefinitelyTyped/DefinitelyTyped/hammerjs/hammerjs.d.ts#de8e80dfe5360fef44d00c41257d5ef37add000a --global --save
Далее нам нужно создать пользовательское переопределение конфигурации класса. Этот класс можно использовать для переопределения всех параметров конфигурации hammerjs и angular2 hammerjs по умолчанию.
молоток.конфиг.ТС:
import { HammerGestureConfig } from '@angular/platform-browser';
import {HammerInstance} from "@angular/platform-browser/src/dom/events/hammer_gestures";
export class HammerConfig extends HammerGestureConfig {
buildHammer(element: HTMLElement): HammerInstance {
var mc = new Hammer(element);
mc.get('pinch').set({ enable: true });
mc.get('rotate').set({ enable: true });
mc.add( new Hammer.Swipe({ direction: Hammer.DIRECTION_ALL, threshold: 0 }) );
for (let eventName in this.overrides) {
mc.get(eventName).set(this.overrides[eventName]);
}
return mc;
}
}
последнее, что нам нужно сделать, это открыть наши главные boostrap-файл и вставьте нашу пользовательскую конфигурацию в метод boostrap следующим образом:
// ... other imports ...
import { HammerConfig } from './shared/hammer.config';
bootstrap(AppComponent, [
provide(HAMMER_GESTURE_CONFIG, { useClass: HammerConfig })
]);
теперь в нашем приложении мы можем использовать swipeDown и swipeUp
<div class="some-block" (swipeDown)="onSwipeDown"></div>
этот запрос pull включен переопределение настроек по умолчанию и дал мне отправную точку, чтобы найти правильный путь:
вам нужно добавить
HelperService
и HammerGesturesPluginCommon
провайдерам где-то, либо в @Component(...)
аннотации или bootstrap(AppComponent, [...])
, чтобы избавиться от ошибки "нет провайдера ..."
вы добавили тег скрипта для Hammer.js
где-то на странице входа?