Как я могу запустить пользовательское событие от Polymer Dart?
Я хочу запустить/отправить/исправить пользовательское событие изнутри элемента Polymer. Например, я хочу преобразовать нормальное событие DOM, например "изменено", в более семантическое событие типа "todoupdated".
Это HTML, который у меня есть:
<polymer-element name="todo-item" extends="li" attributes="item">
<template>
<style>
label.done {
color: gray;
text-decoration: line-through;
}
</style>
<label class="checkbox {{item.doneClass}}">
<input type="checkbox" checked="{{item.done}}">
{{item.text}}
</label>
</template>
<script type="application/dart" src="todo_item.dart"></script>
</polymer-element>
Я хочу, чтобы события изменений на флажке выходили из пользовательского элемента как нечто более... полезное.:)
Ответы
Ответ 1
Шаг 1
Захват событий изменений на <input>
. Обратите внимание на on-change
ниже.
<!-- from inside todo_item.html -->
<input type="checkbox" checked="{{item.done}}" on-change="{{change}}">
Шаг 2
Обработать событие изменения в коде пользовательского элемента, который содержит этот флажок.
import 'package:polymer/polymer.dart';
import 'dart:html';
import 'models.dart';
@CustomTag('todo-item')
class TodoItemElement extends PolymerElement with ObservableMixin {
@observable Item item;
bool get applyAuthorStyles => true;
void change(Event e, var details, Node target) {
// do stuff here
}
}
Обратите внимание на обработчик события change
. Этот метод запускается каждый раз при изменении состояния флажка.
Шаг 3
Отправка пользовательского события.
void change(Event e, var details, Node target) {
dispatchEvent(new CustomEvent('todochange'));
}
ПРИМЕЧАНИЕ: имя настраиваемого события не должно содержать тире.
Шаг 4
Слушайте пользовательское событие в родительском настраиваемом элементе.
<template repeat="{{item in items}}" >
<li is="todo-item" class="{{item.doneClass}}" item="{{item}}" on-todochange="todoChanged"></li>
</template>
Обратите внимание на использование on-todochange
.
Наслаждайтесь!
Ответ 2
Полимер имеет вспомогательный метод, который упрощает события стрельбы
// dispatch a custom event
this.fire('polymer-select', detail: {'item': item, 'isSelected': isSelected});
Дополнительная информация:
Чтобы сделать событие доступным для подписчика, который хочет добавить слушателя программно
// getter
async.Stream<dom.CustomEvent> get onPolymerSelect =>
PolymerSelection._onPolymerSelect.forTarget(this);
// private EventStreamProvider
static const dom.EventStreamProvider<dom.CustomEvent> _onPolymerSelect =
const dom.EventStreamProvider<dom.CustomEvent>('polymer-select');
подписываться на событие программно, а не декларативно:
($['#ps'] as PolymerSelect) // get the children and cast it to its actual type
.onPolymerSelect.listen((e) => print(e['isSelected'])); // subscribe
Ответ 3
Мне это удалось с помощью <core-signals>
и метода полимерного помощника fire
. Таким образом, вы можете слушать события, выпущенные из элементов, которые не являются дочерними. источник.
todochange.html
<!doctype html>
<polymer-element name="todo-item" extends="li">
<template>
<style>
label.done {
color: gray;
text-decoration: line-through;
}
</style>
<label class="checkbox {{item.doneClass}}">
<input type="checkbox" checked="{{item.done}}">
{{item.text}}
</label>
</template>
<script type="application/dart" src="todo_item.dart"></script>
</polymer-element>
todochange.dart
import 'package:polymer/polymer.dart';
import 'dart:html';
@CustomTag('todo-item')
class TodoItemElement extends PolymerElement {
@observable Item item;
void change(Event e, var details, Node target) {
// the name is the name of your custom event
this.fire( "core-signal", detail: { "name": "todochange" } );
}
}
Тогда любой абонент просто должен это сделать
subscriber.html
...
<link rel="import" href="packages/core_elements/core_signals.html>
...
<template>
<core-signals on-core-signal-todochange="{{handleToDoChange}}"></core-signals>
...
</template>
subscriber.dart
@CustomTag( "subscriber" )
class Sub extends PolymerElement {
...
void handleToDoChange( Event e, var detail, Node target ) {
print( "Got event from <todo-item>" );
}
...
}