Skip to content
This repository has been archived by the owner on Sep 16, 2022. It is now read-only.

template recursion without Map support #1918

Open
4 tasks done
insinfo opened this issue Oct 1, 2020 · 1 comment
Open
4 tasks done

template recursion without Map support #1918

insinfo opened this issue Oct 1, 2020 · 1 comment

Comments

@insinfo
Copy link

insinfo commented Oct 1, 2020

  • Dart SDK Version Dart VM version: 2.8.4 (stable) (Wed Jun 3 12:26:04 2020 +0200) on "windows_x64"
  • AngularDart Version ^6.0.0-alpha+1
  • Windows
  • Chrome

how to deal with recursion in Template without Map support?
I have a project that I am migrating from AngularDart 5.3.1 to AngularDart 6.0.0-alpha + 1, which uses recursion in the Template to create a Menu recursively, it works well in AngularDart 5.3.1, more in AngularDart 6 Map support was removed and now I don't know how to pass the context map

<div *ngIf="list?.isNotEmpty == true" class="card card-sidebar-mobile">
            <ul #ulroot class="nav nav-sidebar" data-nav-type="accordion">
                <template #recursiveList let-list>                  
                   
                    <li class="nav-item " *ngFor="let item of list; let i = index"
                      [class.nav-item-submenu]="item.children.length > 0" [class.nav-item-open]="item.level == 0">
                   
                        <a #anchorElement [attr.data-rota]="item.rota" class="nav-link item"
                            (click)="toogleSubMenuhtml(anchorElement, item)"
                            [class.nav-link-level-1]="item.level == 1"
                             [hidden]="item.filter == false">
                            <i [class]="item.icone" *ngIf="item.icone != null"></i>
                            <span>{{item.label}}</span>
                        </a>
                        <ul class="nav nav-group-sub" *ngIf="item.children.length > 0"
                            [style.display]="item.isCollapse==false  ? 'block': 'none'">
                            <!--<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.children }">-->
                            <ng-container *ngTemplateOutlet="recursiveList">
                            </ng-container>
                        </ul>
                    </li>
                </template>
                <!-- <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: list }"></ng-container> -->
                <ng-container *ngTemplateOutlet="recursiveList"></ng-container>
            </ul>          
        </div>

image

@ygordaudt
Copy link

I'm with the same problem.

I found a solution , but I'm don't know it is the best way to fix the problem.

This solution unfortunately causes Angular to redraw objects on the screen all the time, since, as the property is a computed function, and Angular's change detector causes the ngTemplateOutlet to be called at all times.

extension TemplateOutletContextForRender on RList {
  // this is for the compatibility with the Angular 6.0
 //ngTemplateOutlet <ng-container *ngTemplateOutlet="recursiveList; context: item.contextForRender ">
  Map<String, dynamic> get templateOutletContext {
    return {'\$implicit': this};
  }
}

In component Controller

class MenuItem {
  int id;
  int idPai;
  String rota;
  String label;
  String icone;
  String cor;
  int ordem;
  bool ativo;
  int idSistema;
  RList<MenuItem> children = RList<MenuItem>();
  int level;
  bool filter;
  MenuItem parent;
  bool isCollapse = true;

  bool hasChilds(MenuItem item) {
    return item.children?.isNotEmpty == true;
  }

  //this is for the compatibility with the Angular 6.0
// ngTemplateOutlet <ng-container *ngTemplateOutlet="recursiveList; context: item.templateOutletContext ">
  Map<String, dynamic> get templateOutletContext => {'\$implicit': children};

  bool finded(String _search_query, MenuItem item) {
    var item_title = Utils.removerAcentos(item.label).toLowerCase();
    //return item_title.contains(_search_query);
    return (item_title.indexOf(_search_query) != -1);
  }

  MenuItem clone() {
    return MenuItem.fromJson(toJson());
  }

  MenuItem.fromJson(Map<String, dynamic> json) {
    try {
      id = Utils.isNotNullOrEmptyAndContain(json, 'id') ? json['id'] : null;
      idPai = Utils.isNotNullOrEmptyAndContain(json, 'idPai') ? json['idPai'] : null;
      label = Utils.isNotNullOrEmptyAndContain(json, 'label') ? json['label'] : null;
      icone = Utils.isNotNullOrEmptyAndContain(json, 'icone') ? json['icone'] : null;
      ordem = Utils.isNotNullOrEmptyAndContain(json, 'ordem') ? json['ordem'] : null;
      ativo = Utils.isNotNullOrEmptyAndContain(json, 'ativo') ? json['ativo'] : null;
      idSistema = Utils.isNotNullOrEmptyAndContain(json, 'idSistema') ? json['idSistema'] : null;
      rota = Utils.isNotNullOrEmptyAndContain(json, 'rota') ? json['rota'] : '#';
      level = Utils.isNotNullOrEmptyAndContain(json, 'level') ? json['level'] : null;
      if (Utils.isNotNullOrEmptyAndContain(json, 'nodes')) {
        children = RList<MenuItem>();
        json['nodes'].forEach((v) {
          children.add(MenuItem.fromJson(v));
        });
      }
    } catch (e) {
      print('MenuItem.fromJson: ${e}');
    }
  }

  Map<String, dynamic> toJson() {
    final json = <String, dynamic>{};
    if (id != null) {
      json['id'] = id;
    }
    json['idPai'] = idPai;
    json['label'] = label;
    json['icone'] = icone;
    json['cor'] = cor;
    json['ordem'] = ordem;
    json['idSistema'] = idSistema;
    json['rota'] = rota;
    json['level'] = level;

    if (children != null && children.isNotEmpty) {
      json['nodes'] = children.map((v) => v.toJson()).toList();
    }

    return json;
  }

}


RList<MenuItem> list = RList<MenuItem>();

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants