Как веб-компонент Dart может получить ссылку на своих дочерних элементов?

Для наглядности я создал класс, унаследованный от WebComponent, с именем FancyOption, который меняет цвет фона на заданный текстом в одном дочернем элементе при нажатии на другой дочерний элемент.

import 'package:web_ui/web_ui.dart';
import 'dart:html';

class FancyOptionComponent extends WebComponent {
  ButtonElement _button;
  TextInputElement _textInput;

  FancyOptionComponent() {
    // obtain reference to button element
    // obtain reference to text element

    // failed attempt
    //_button = this.query('.fancy-option-button');
    // error: Bad state: host element has not been set. (no idea)

    // make the background color of this web component the specified color
    final changeColorFunc = (e) => this.style.backgroundColor = _textInput.value;
    _button.onClick.listen(changeColorFunc);
  }
}

FancyOption HTML:

<!DOCTYPE html>

<html>
  <body>
    <element name="x-fancy-option" constructor="FancyOptionComponent" extends="div">
      <template>
        <div>
          <button class='fancy-option-button'>Click me!</button>
          <input class='fancy-option-text' type='text'>
        </div>
      </template>
      <script type="application/dart" src="fancyoption.dart"></script>
    </element>
  </body>
</html>

У меня есть три из них на странице, как это.

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <title>Sample app</title>
    <link rel="stylesheet" href="myapp.css">
    <link rel="components" href="fancyoption.html">
  </head>
  <body>
    <h3>Type a color name into a fancy option textbox, push the button and 
    see what happens!</h3>

    <div is="x-fancy-option" id="fancy-option1"></div>
    <div is="x-fancy-option" id="fancy-option2"></div>
    <div is="x-fancy-option" id="fancy-option3"></div>

    <script type="application/dart" src="myapp.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

person Phlox Midas    schedule 06.04.2013    source источник


Ответы (2)


Просто используйте getShadowRoot() и запросите его:

import 'package:web_ui/web_ui.dart';
import 'dart:html';

class FancyOptionComponent extends WebComponent {
  ButtonElement _button;
  TextInputElement _textInput;

  inserted() {
    // obtain references
    _button = getShadowRoot('x-fancy-option').query('.fancy-option-button');
    _textInput = getShadowRoot('x-fancy-option').query('.fancy-option-text');

    // make the background color of this web component the specified color
    final changeColorFunc = (e) => this.style.backgroundColor = _textInput.value;
    _button.onClick.listen(changeColorFunc);
  }
}

Где x-fancy-option строка — это имя элемента.

Примечание. Я изменил ваш конструктор на метод inserted(), который является методом жизненного цикла.

person Kai Sellgren    schedule 07.04.2013
comment
Я пробовал это. Он не падает, но теперь не отображает компоненты. Выдает предупреждение: «_root не является членом FancyOptionComponent». SDK версии 0.4.4.4_r20810 - person Phlox Midas; 08.04.2013
comment
О, теперь я знаю, почему. Вы должны делать свою логику в inserted(), а не в конструкторе. Я обновлю свой ответ. - person Kai Sellgren; 08.04.2013
comment
Блестящий. Это сработало. Интересно, что _root по-прежнему генерирует это предупреждение, но поведение программы такое, как я хочу, поэтому я вполне доволен. Спасибо, Кай. - person Phlox Midas; 08.04.2013

Я понимаю, что _root устарел. Ответы, рекомендующие _root, должны использовать getShadowRoot() вместо _root.

person Ken M    schedule 13.05.2013
comment
Превосходно. Спасибо за отзыв. - person Phlox Midas; 15.05.2013