AngularDart: нельзя привести к материальному компоненту

У меня есть приложение для дротиков, содержащее шаблон с флажком материала, который я не могу использовать в своем компоненте. Вот простой шаблон для демонстрации проблемы (two_boxes.html):

<!--
Simple HTML to test checkboxes
-->

<input type="checkbox" id="cb0">
<label>Standard Checkbox</label>

<material-checkbox label="Material Checkbox" id="cb1">
</material-checkbox>

<button (click)="doTest()">Test</button>

и соответствующий компонент, в котором я пытаюсь использовать флажки (two_boxes.dart). Я могу использовать стандартный флажок в приведении, как и ожидалось, но не могу найти способ сделать то же самое с флажком материала:

// Component for testing

import 'package:angular/angular.dart';
import 'package:angular_components/angular_components.dart';

import 'dart:html';

@Component(
    selector: 'two-boxes',
    templateUrl: 'two_boxes.html',
    directives: const [MaterialCheckboxComponent],
    pipes: const [
      COMMON_PIPES
    ])
class TwoBoxes {

  // Get the the two checkboxes and see if they are checked
  void doTest() {
    var checkbox_standard = querySelector("#cb0");
    print(checkbox_standard.runtimeType.toString()); // InputElement
    print((checkbox_standard as CheckboxInputElement).checked); // Succeeds

    var checkbox_material = querySelector("#cb1");
    print(checkbox_material.runtimeType.toString()); // HtmlElement
    print((checkbox_material as MaterialCheckboxComponent).checked); // Error!
  }
}

Последний оператор терпит неудачу, когда я запускаю приложение в Dartium после «обслуживания в пабе» (без ошибок) с:

VM54:1 EXCEPTION: type 'HtmlElementImpl' is not a subtype of type
MaterialCheckboxComponent' in type cast where HtmlElementImpl is 
from dart:html MaterialCheckboxComponent is from   
package:angular_components/src/components/
material_checkbox/material_checkbox.dart

Ясно, что этот способ литья не работает. Я часами искал, как решить эту ошибку и найти правильный способ сделать это, но, очевидно, не в тех местах. Что мне здесь не хватает? Я использую Dart VM версии 1.24.2.


person user3449401    schedule 08.09.2017    source источник


Ответы (1)


Невозможно получить экземпляр компонента из запрошенного таким образом элемента.

Вы можете использовать @ViewChild()

class TwoBoxes implements AfterViewInit {

  @ViewChild(MaterialCheckboxComponent) MaterialCheckboxComponent cb;

  ngAfterViewInit() {
    print(cb.checked);
  }

чтобы получить конкретный, если у вас их несколько, вы можете использовать переменную шаблона

<material-checkbox #foo label="Material Checkbox">

с

@ViewChild('foo') MaterialCheckboxComponent cb;

Вы можете найти дополнительную информацию по этой теме в этом ответе TypeScript angular 2 / typescript: получить элемент в шаблоне

Синтаксис немного отличается (введите аннотации справа и {} вокруг необязательного параметра read, которые не используются в Dart.

person Günter Zöchbauer    schedule 08.09.2017
comment
Работает как шарм, только что попробовал. Я искал некоторую информацию о крючках жизненного цикла. Почему вы специально реализовали AfterViewInit, а не, например, AfterViewChecked? Является ли рендеринг завершенным при выполнении AfterViewInit? Кстати, спасибо Гюнтер. - person user3449401; 08.09.2017
comment
ngAfterViewInit вызывается ровно один раз после инициализации представления и содержимого. ngAfter*Checked можно вызывать более одного раза. angular.io/guide/lifecycle-hooks - person Günter Zöchbauer; 10.09.2017