I would like to aggregate statically defined child components with dynamical once that might be sourced from the stream. I want a generic way to define carousel in this carousel where I can have a typed collection of components. The collection can be defined statically or dynamically. Below is an example:
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");
}
}
in my dashboard component, I have statically defined the usage as follows:
<md-texts>
<md-text [name]="'Liberty'"></md-text>
<md-text [name]="'Life'"></md-text>
<md-texts>
The display is as following United States Liberty Life
What I want to do is have the "Liberty" and "Life" also be aggregated to my component collection, so I can control it with the next and previous button. I also only want to render them when their index is called for. What is the best way to do this in AngularDart.
I found a similar question with old version but with older version How to reference child component from its parent in AngularDart in AD 1.0.0 and How to reference child component from its parent in AngularDart in AD 1.0.0
Regards, Hopefully i have explained my problem and i will get clear direction on what is the correct way of addressing this design issue.
You can use @ViewChildren
and @ContentChildren
to query for child components. @ViewChildren
will query for components declared in your template, whereas @ContentChildren
will query for components projected into an <ng-content>
in your template.
It's worth mentioning that in your example, your dynamic TextComponent
is being created twice. First, you create one in your constructor, then again when you declare a <md-text>
in your template. This means the instance you're keeping a reference to, isn't actually the component rendered in your view. To avoid this, don't bother creating the instance imperatively. Just keep a model of the data needed to create them, then pass that through inputs in your template where you declare the components. You can then use @ViewChildren
to query for those components you've created.
Here's an example
@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 = [
...
];
}
Alternatively, you could render all of the <md-text>
from a single source of data in your view, and rely on passing in a model for the static data rather than projecting the components.