简体   繁体   English

Angular 2:递归组件的@ViewChildren

[英]Angular 2 : @ViewChildren for recursive component

I have a recursive component which displays des tag a我有一个递归组件,它显示 des 标签 a

First , there is the parent component - html首先,有父组件 - html

<div class=" suggestions" style="display : inline-block;" tabindex=-1 #autocompleteDiv>
     <span style="width: auto;cursor: pointer;position: absolue">
      <div *ngIf="hideInputField" style="border: 1px solid #9e9898">
          {{query}}
          <a style="color: #0012ff;" (click)="unselectData()">x </a>
      </div>
      <div *ngIf="!hideInputField">
        <input  type="text" [(ngModel)]="query"  (keyup)="handleKeyPress($event)" (keypress)="handleEnterPress($event)"
                style="padding: 4px;" (click)="displayDropdown();" #inputquery  (selectValueEvent)="select($event)">
        <div  #suggestion  *ngIf="divMustBeShow===true"  tabindex="-1">

          <div #recursivediv class="liclass" >
               <recursive-tree-view [treeNodeDisplay]="listToBuild"
                     [selectedItem]="selectedItem"
                     (selectValueEvent)="select($event)" #recursive></recursive-tree-view>
          </div>
        </div>
      </div>
  </span>
</div>

parent code (a part) :父代码(一部分):

   displayDropdown() {
    if (this.divMustBeShow) {
        if ((this.query && this.query.length < 1) || !this.query) {
            this.divMustBeShow = false;
        }
    } else {
        this.divMustBeShow = true;

    }
}

handleEnterPress(key: KeyboardEvent) {

    if (key.keyCode === 13 || key.keyCode === 20) {
        //when press enter (13) or tab (20)
        this.query = this.recursive.selecItemWithEnterPress();
    }
}


handleKeyPress(key: KeyboardEvent) {
    if (key.key === "ArrowDown") {
        // if the pressed key is down arrow
        this.recursive.setDownListFocus()
    } else if (key.key === "ArrowUp") {
        // if the pressed key is up arrow
        this.recursive.setUpListFocus();
    } else if (key.keyCode === 13 || key.keyCode === 20) {
        //when press enter (13) or tab (20)
        this.query = this.recursive.selecItemWithEnterPress();
    } else if ((key.keyCode > 64 && key.keyCode < 91)   // key a -> z
        || key.keyCode === 32 // space
        || key.keyCode === 8 //  backspace
        || key.keyCode === 46 // delete
        || (key.keyCode > 47 && key.keyCode < 57) // 1-> 9
        || (key.keyCode > 95 && key.keyCode < 106))// 1-9 (numpad)
        if (this.query && this.query.length > 1) {
            this.divMustBeShow = true;
            this.listToBuild = this.filterFunction(this.query, this.originalMap, this.userLanguage);
        }
        else {
            this.divMustBeShow = true;
            this.listToBuild = this.filterFunction("", this.originalMap, this.userLanguage);
        }
}

html of component recursive-tree-view :组件递归树视图的 html :

  <li *ngFor="let treeNode of treeNodeDisplay.getChildren(); let x = index;" style="cursor: default;">
     <div *ngIf="!treeNode.canBeClickable()">
          {{treeNode.getLabel()}}
      </div>
      <div *ngIf="treeNode.canBeClickable()">
      <a  #item (click)="select(treeNode.getId())" >
         {{treeNode.getLabel()}} </a>
       </div>
    <div *ngIf="nodeHasChildren(treeNode)">
         <recursive-tree-view [treeNodeDisplay]="treeNode"                       (selectValueEvent)="select($event)"  > </recursive-tree-view>
    </div>
  </li>
</ul>

in the component, i want to have of list of all (thus a list of #item)在组件中,我想要所有列表(因此是#item 列表)

   @ViewChildren(forwardRef(() => "item"))
itemsList: QueryList<ElementRef>;
setDownListFocus() {
    if (this.lineCounter < this.itemsList.toArray().length) {

        if (this.lineCounter > 0) {  // one item is already selected
            //unselected previous element
            this._renderer.setElementStyle(this.itemsList.toArray()[this.lineCounter - 1].nativeElement, 'font-weight', 'normal');

        }
        this._renderer.setElementStyle(this.itemsList.toArray()[this.lineCounter].nativeElement, 'font-weight', 'bold');
        this.lineCounter++;
    }
}

setUpListFocus() {
    if (this.lineCounter > 0) {
        this.lineCounter--;
        this._renderer.setElementStyle(this.itemsList.toArray()[this.lineCounter - 1].nativeElement, 'font-weight', 'bold');
        this._renderer.setElementStyle(this.itemsList.toArray()[this.lineCounter].nativeElement, 'font-weight', 'normal');
    }

}

lineCounter is set to 1 in ngOnInit of recursive component lineCounter 在递归组件的 ngOnInit 中设置为 1

the display result is :显示结果为:

.....  (input text)
  node 1
     result1   => the first element must be in bold
     result2
  node2
     result3
     result4
     result5

when the user press arrowDown key , the first element(thus result1) must have font normal and the second (thus result2) must be in bold Next if the user press again arrowDown key , the second element (result2) must be normal and the hirs element (result 3) must be in bold next if the user press upDown key , the third element (result3) must be normal and the second element must be in bold.当用户按下箭头向下键时,第一个元素(因此 result1)的字体必须正常,第二个(因此 result2)必须是粗体 下一步如果用户再次按下箭头向下键,第二个元素(result2)必须是正常的,并且 hirs如果用户按下向上键,则元素(结果 3)接下来必须以粗体显示,第三个元素(结果 3)必须是正常的,第二个元素必须是粗体。

The element node cannot be in bold元素节点不能为粗体

@ViewChildren() only works for direct children. @ViewChildren()仅适用于直系孩子。

A workaround would be a shared service where each treeNode registers itself when it is created and removes itself in ngOnDestroy .解决方法是共享服务,其中每个treeNode在创建时注册自己并在ngOnDestroy删除自己。

The service can't be registered on a treeNode otherwise each treeNode would get its own instance.该服务不能在treeNode上注册,否则每个treeNode都会获得自己的实例。 It has to be a parent of the root node or the root module.它必须是根节点或根模块的父节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM