How to call methods on subcomponents in Angular dart?

Issue

I’m building a component containing roles. This is the components source code

role_chooser_comp.html

<div class="roleChooser">
  <role-item #owner (select)="selected(owner.role)" [role]="'owner'" [title]="'Owner'" [desc]="'Can write'"></role-item>
  <role-item #writer (select)="selected(writer.role)" [role]="'writer'" [title]="'Writer'" [desc]="'Can write'"></role-item>
  <role-item #viewer (select)="selected(viewer.role)" [role]="'viewer'" [title]="'Reader'" [desc]="'Can write'"></role-item>
</div>

it is composed of multiple items
role_item.html

<div class="role" [class.selected]="selected" (click)="clicked()">
  <btn
      [sources]="images"></btn>
  <span class="title">{{title}}</span>
  <div class="desc">{{desc}}</div>
</div>

Now I want to be able to unselect all items except the one that is pressed. For that, I have a select @output in each item to notify the parent:

import 'package:angular2/core.dart';
import 'package:angular2/router.dart';

import 'package:share_place/environment.dart';
import 'package:share_place/place_service.dart';

import 'package:share_place/common/ui/button_comp.dart';

@Component(
    selector: 'role-item',
    templateUrl: 'role_item.html',
    styleUrls: const ['role_item.css'],
    directives: const [ButtonComp])
class RoleItem {
  final PlaceService _placeService;
  final Router _router;
  final Environment _environment;
  @Output() final EventEmitter<String> pressAction = new EventEmitter<String>();
  @Output() final EventEmitter<String> select = new EventEmitter<String>();

  get role => itemRole;

  @Input() set role(String role) {
    itemRole = role;
    images = [
      '../images/roles/$role.bmp',
      '../images/roles/$role-h.bmp',
      '../images/roles/$role-c.bmp'
    ];
  }

  @Input() String title;
  @Input() String desc;

  String itemRole;

  List<String> images;

  bool selected = false;
  bool toggle = true;

  RoleItem(this._placeService, this._router, this._environment);

  void clicked() {
    bool newlySelected;
    if (!selected)
      newlySelected = true;

    if (toggle)
      selected = !selected;
    else
      selected = true;

    pressAction.emit(role);
    if (newlySelected)
      select.emit(role);
  }
}

All this works pretty well, but in my role chooser, I want to put the children components in a list to be able to loop over them on each select and unselect them.

import 'package:angular2/core.dart';
import 'package:angular2/router.dart';

import 'package:share_place/environment.dart';
import 'package:share_place/place_service.dart';

import 'package:share_place/common/ui/button_comp.dart';
import 'package:share_place/users/role/role_item.dart';

@Component(
    selector: 'role-chooser-comp',
    templateUrl: 'role_chooser_comp.html',
    styleUrls: const ['role_chooser_comp.css'],
    directives: const [RoleItem])
class RoleChooser {
  final PlaceService _placeService;
  final Router _router;
  final Environment _environment;

  RoleChooser(this._placeService, this._router, this._environment);

  void selected(String role) {
    print("Role selected : $role");
  }
}

Is there (ideally) any way to do that without having the children types refrenced in the parent? (to keep the view independent of the controller)?

thanks for your help!

Solution

In RoleChooser, you can use @ViewChildren

https://webdev.dartlang.org/angular/api/angular2.core/ViewChildren-class

@ViewChildren(RoleItem)
QueryList<RoleItem> items;

for (RoleItem item in items) {
  item.doSomething();
}

Answered By – Hadrien Lejard

Answer Checked By – Gilberto Lyons (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.