Zied Hamdi
Zied Hamdi

Reputation: 2662

How to call methods on subcomponents in Angular dart?

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!

Upvotes: 0

Views: 556

Answers (1)

Hadrien Lejard
Hadrien Lejard

Reputation: 5924

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();
}

Upvotes: 3

Related Questions