Полимерные события от удаленных узлов

Я пытаюсь познакомиться с полимером и пытаюсь создать с ним образец приложения. Следуя руководствам на https://www.dartlang.org/docs/tutorials/polymer-intro и чтение других вопросов StackOverflow, таких как Как запустить пользовательское событие из Polymer Dart? Мне удалось создать два элемента, в которых один элемент запускает событие, на которое действует второй элемент. Однако мне удалось выяснить, как это сделать только в тех случаях, когда активирующий элемент является дочерним элементом прослушивающего элемента. Например, следующим образом

foo.html

<link rel="import" href="bar.html">
<polymer-element name="foo">
    <template>
        <my-bar on-myevent="{{react}}"></mybar>
    </template>
    <script type="application/dart" src="foo.dart"></script>
</polymer-element>

foo.dart

@CustomTag('my-foo')
class Foo extends PolymerElement {

  Foo() {}
  Foo.created() : super.created();

  void react() {
    print("Event happened and was heard!");
  }
}

bar.html

<polymer-element name="bar">
    <template>
        <button on-click="{{click}}"></button>
    </template>
    <script type="application/dart" src="bar.dart"></script>
</polymer-element>

bar.dart

@CustomTag('my-bar')
class Bar extends PolymerElement {

  Bar() {}
  Bar.created() : super.created();

  void click(Event e, var details, Node node) {
    print("Triggering event");
    fire('my-event');
  }
}

index.html

<!DOCTYPE html>
<html>
<head>
    <script type="application/dart" src="main.dart"></script>
    <script src="packages/browser/dart.js"></script>
    <link rel="import" href="foo.html">
</head>
<body>

<div id="content">
    <foo></foo>
</div>

</body>
</html>

Что я хотел бы сделать, так это иметь возможность перемещать кнопку bar за пределы элемента foo, так как в приложении, которое я хочу разработать, я хотел бы, чтобы элементы управления вводом существовали в отдельной области страницы от основного вывода. дисплей (элемент foo). По сути, я бы хотел, чтобы foo.html и index.html выглядели так:

foo.html

<polymer-element name="foo">
    <template>
        <!-- Databound output stuff here -->
    </template>
    <script type="application/dart" src="foo.dart"></script>
</polymer-element>

index.html

<!DOCTYPE html>
<html>
<head>
    <script type="application/dart" src="main.dart"></script>
    <script src="packages/browser/dart.js"></script>
    <link rel="import" href="foo.html">
    <link rel="import" href="bar.html">
</head>
<body>

<div id='control-panel'>
    <bar></bar>
</div>
<div id="content">
    <foo></foo>
</div>

</body>
</html>

Кажется, я не могу найти примеров того, как, если я перемещаю кнопку bar из элемента foo, чтобы событие от bar было видно foo. Как лучше всего прослушать событие от bar, если оно не является дочерним элементом foo?


person Michael Fenwick    schedule 30.05.2014    source источник


Ответы (3)


Polymer разработан вокруг идеи controllers. Под этим я подразумеваю, что когда A и B необходимо какое-то взаимодействие, предпочтительной архитектурой является создание третьей сущности C. C может управлять жизненным циклом A и B и организовывать общение. Структура такого типа отлично подходит для сопровождения, потому что пользователи C изолированы от деталей A и B, а A и B изолированы от всего. Он также обеспечивает удобное место для согласования импеданса между A и B.

<polymer-element name="my-c">
 <template>
  <my-a on-my-event="{{coolAction}}"></my-a>
  ...
  <my-b id="b"></my-b>
 </template>
 <script>
   Polymer({
    coolAction: function() {
      this.$.b.doCoolThing();
    }
   });
 </script>
</polymer-element>

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

В конечном счете, ваше представление представляет собой граф компонентов, где любой конкретный подграф обычно можно отрезать, заменить или снова присоединить с минимальными усилиями. Это отлично подходит для создания гибких приложений.

Концепция signals существует для тех редких случаев, когда вы действительно хотите, чтобы A и B общались друг с другом напрямую, пересекая граф компонентов. Эта возможность почти никогда не требуется при хорошем дизайне приложения, и ее следует по возможности избегать.

person Scott Miles    schedule 30.05.2014

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

Допустим, у вас есть эта структура:

<div id="event-bus">
  <my-a></my-a>
  <my-b></my-b>
</div>

Затем <my-b> сможет прослушивать мое событие на #event-bus.

Чтобы помочь найти шину событий, вы можете установить атрибут:

<div id="event-bus">
  <my-a></my-a>
  <my-b event-bus="event-bus"></my-b>
</div>
class MyB extends PolymerElement {

  @published String eventBus;

  ready() {
    querySelector('#$eventBus').on['my-event'].listen((e){ react(); } );
  }

  ...
}
person Justin Fagnani    schedule 30.05.2014

Элемент <polymer-signals> был перенесен в Dart, что позволяет запускать пользовательское событие где угодно и прослушивать его где угодно.

Используйте его как <polymer-signals on-polymer-signalfoo="{{foo}}"></polymer-signals>, где тип события, который вы запускаете, — polymer-signal, а данные пожара содержат {'name': 'foo', 'data': <your-data>}.

Порт находится здесь polymer_elements for dart.

Хорошее объяснение событий в целом для полимера javascript, которое также описывает, как работает <polymer-signals>, описано коммуникация и передача сообщений.

person tusj    schedule 30.05.2014