AngularDart - способ агрегировать статически определенный дочерний компонент с динамическим один раз

Я хотел бы объединить статически определенные дочерние компоненты с динамическими однократными, которые могут быть получены из потока. Мне нужен общий способ определения карусели в этой карусели, где я могу иметь типизированную коллекцию компонентов. Коллекция может быть определена статически или динамически. Ниже приведен пример:

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


/**
 *
 */
@Component(
    selector: 'md-text',
    styleUrls: const ['md_text.css'],
    template: '<li>{{name}}</li>',
    directives: const [
      materialDirectives,
    ]
)
class TextComponent implements OnInit{
  @Input()
  String name;

  TextComponent([this.name]);

  TextComponent.withName(String name)
      : this(name);

  @override
  ngOnInit() {
  }
}

@Component(
    selector: 'md-texts',
    styleUrls: const ['text_component.css'],
    template: '<ol><md-text *ngFor="let component of components" [name]="component.name"></md-text><ng-content></ng-content></ol>',
    directives: const [
      CORE_DIRECTIVES,
      materialDirectives,
      TextComponent
    ]
)
class TextsComponent<TextComponent> implements OnInit
{
  Set<T> _components;

  Set<T> get components => _components;

  addComponent(T component){
    this._components.add(component);
  }

  removeComponent(T component) {
    this._components.remove(component);
  }

  TextsComponent() {
    this._components = new LinkedHashSet<T>();
    TextComponent declarativeChannel = new TextComponent.withName("United States");
    this.addComponent(declarativeChannel);
  }

  @override
  ngOnInit(){
    print("I am here");
  }
}

в моем компоненте приборной панели я статически определил использование следующим образом:

<md-texts>
    <md-text [name]="'Liberty'"></md-text>
    <md-text [name]="'Life'"></md-text> 
<md-texts>

Дисплей выглядит следующим образом: United States Liberty Life

Я хочу, чтобы «Свобода» и «Жизнь» также были объединены в мою коллекцию компонентов, чтобы я мог управлять ими с помощью кнопок «Далее» и «Назад». Я также хочу отображать их только тогда, когда требуется их индекс. Как лучше всего это сделать в AngularDart.

Я нашел аналогичный вопрос со старой версией, но со старой версией Как ссылаться на дочерний компонент из его родителя в AngularDart в AD 1.0.0 и Как ссылаться на дочерний компонент из его родителя в AngularDart в AD 1.0.0

С уважением, Надеюсь, я объяснил свою проблему и получу четкое указание о том, как правильно решить эту проблему с дизайном.


person TiKi    schedule 07.12.2017    source источник
comment
Я не совсем понимаю, о чем вы просите, но это может быть похоже на stackoverflow.com/questions/36325212/   -  person Günter Zöchbauer    schedule 07.12.2017
comment
@ GünterZöchbauer, мой вопрос немного отличается, я знаю, как использовать динамические компоненты. Но вопрос в том, как определение статического компонента может быть обнаружено (обнаружено) родительским компонентом. В моем случае тексты - это родительский компонент. Текст - это дочерние компоненты. Когда я использую его статически в разметке, как их можно добавить в компоненты моей коллекции в приведенном выше примере? Если вы посмотрите на код, который я внедряю в экземпляр United States через конструктор и Life, Liberty через разметку, коллекция компонентов знает только Соединенные Штаты, как я могу сообщить ему о Life и Liberty.   -  person TiKi    schedule 07.12.2017
comment
Я думаю, вам нужен подход, подобный показанному в моем связанном ответе. Просто добавьте их динамически, и тогда вы сможете управлять ими. Вы не можете перемещать компоненты, добавленные статически (до сих пор не уверен, что понимаю, чего вы пытаетесь достичь)   -  person Günter Zöchbauer    schedule 07.12.2017


Ответы (1)


Вы можете использовать @ViewChildren и @ContentChildren для запроса дочерних компонентов. @ViewChildren будет запрашивать компоненты, объявленные в вашем шаблоне, тогда как @ContentChildren будет запрашивать компоненты, спроецированные в <ng-content> в вашем шаблоне.

Стоит упомянуть, что в вашем примере ваш динамический TextComponent создается дважды. Сначала вы создаете его в своем конструкторе, а затем снова, когда объявляете <md-text> в своем шаблоне. Это означает, что экземпляр, на который вы ссылаетесь, на самом деле не является компонентом, отображаемым в вашем представлении. Чтобы этого избежать, не беспокойтесь о создании экземпляра императивно. Просто сохраните модель данных, необходимых для их создания, а затем передайте ее через входные данные в своем шаблоне, где вы объявляете компоненты. Затем вы можете использовать @ViewChildren для запроса созданных вами компонентов.

Вот пример

@Component(
  selector: 'md-texts',
  template: '''
    <ol>
      <md-text *ngFor="let text of texts" [text]="text"></md-text>
      <ng-content></ng-content>
    </ol>
  ''',
  directives: const [NgFor, TextComponent],
)
class TextsComponent {
  /// Text that was projected through `<ng-content>`.
  @ContentChildren(TextComponent)
  QueryList<TextComponent> contentTexts;

  /// Text that was created in our view from our model.
  @ViewChildren(TextComponent)
  QueryList<TextComponent> viewTexts;

  /// Data model for the text in our view.
  final List<String> texts = [
    ...
  ];
}

В качестве альтернативы вы можете визуализировать все <md-text> из одного источника данных в вашем представлении и полагаться на передачу модели для статических данных, а не на проектирование компонентов.

person Leon Senft    schedule 07.12.2017
comment
ваш ответ был правильным, я бы хотел, чтобы был способ объединить как viewchild, так и contentchild как одно, но я согласен с вашими комментариями. В идеале было бы просто иметь смысл визуализировать все компоненты из одного списка входных данных или потока. - person TiKi; 08.12.2017