Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 按选择顺序在列表视图中显示层次结构选择_Javascript_Html_Angular_Typescript_Hierarchy - Fatal编程技术网

Javascript 按选择顺序在列表视图中显示层次结构选择

Javascript 按选择顺序在列表视图中显示层次结构选择,javascript,html,angular,typescript,hierarchy,Javascript,Html,Angular,Typescript,Hierarchy,我正在尝试实现一个功能,它将在右侧显示从TreeNode结构中选择的节点列表。 类似于我发现的这个plunkr的东西: 在我当前的方法中,我得到的右侧列表与左侧列表的层次结构顺序相同 例如:即使我在节点“A”之前选择了节点“B”,在列表中,它仍然会先显示A,然后显示B(因为A在显示的层次结构中位于B之上) Rightside.component.html: <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs

我正在尝试实现一个功能,它将在右侧显示从TreeNode结构中选择的节点列表。 类似于我发现的这个plunkr的东西:

在我当前的方法中,我得到的右侧列表与左侧列表的层次结构顺序相同

例如:即使我在节点“A”之前选择了节点“B”,在列表中,它仍然会先显示A,然后显示B(因为A在显示的层次结构中位于B之上)

Rightside.component.html:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  <ul class="selection-list">
    <li *ngFor="let item of getSelections()">
      <button class="btn" (click)="deselect(item)" *ngIf="item.selected">
        <i class="fa fa-close"> {{ item.displayName }} </i>
      </button> 
    </li>
  </ul>

rightside.component.ts:

import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { DataService } from '../../shared/service/data.service';
import { TreeNode } from '../../shared/dto/TreeNode';

import html from './rightside.component.html';
import css from './rightside.component.css';

@Component({
  selector: 'rightside-component',
  template: html,
  providers: [DataService],
  styles: [css],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class RightSideComponent implements OnInit {
  selections: string[];
  @Input() treeNode: TreeNode<string>[];

  constructor(private cd: ChangeDetectorRef) {}

  ngOnInit() {
  }

  getSelections() : TreeNode<string>[] {
    if (typeof(this.treeNode) == "undefined" || (this.treeNode) === null) {
      return [];
    }
    return this.treeNode;
  }

  deselect(item: TreeNode<string>): void {
    if((item.children) !== null) {
      item.children.forEach(element => {
        this.deselect(element);
      });
    }
    item.selected = false;
  }

}
import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import * as API from '../../shared/api-routes';
import { DataService } from '../../shared/service/data.service';
import { ValidationService } from '../../shared/service/validation.service';
import { Subject } from 'rxjs/Subject';
import { BasestepComponent } from '../basestep-component/basestep.component';
import { TreeNode } from '../../shared/dto/TreeNode';

import html from './productline.component.html';
import css from './productline.component.css';

@Component({
  selector: 'productline-component',
  template: html,
  providers: [DataService],
  styles: [css],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class ProductlineComponent extends BasestepComponent<string> implements OnInit {
  selectedProductLine:    TreeNode<string>[];

  constructor(dataService:DataService, cd:ChangeDetectorRef) {
    super(dataService, cd);
  }

  ngOnInit() {
    this.subject.subscribe((productline) => this.productLineChange(productline));
  }

  public productLineChange(productLine: TreeNode<string>[]):void {
    this.selectedProductLine = productLine;
  }

}
import { Input, ChangeDetectorRef } from '@angular/core';
import { castTree, ReportTemplate } from '../report-common';
import { DataService } from '../../shared/service/data.service';
import { Subject } from 'rxjs/Subject';
import { ValidationService } from '../../shared/service/validation.service';
import { TreeNode } from '../../shared/dto/TreeNode';

export class BasestepComponent<T> {
  public tree: TreeNode<T>;
  public singleSelect: boolean = false;
  public isDataLoaded: boolean;
  public template: ReportTemplate;
  @Input() templateSubject: Subject<ReportTemplate>;
  @Input() subject: Subject<TreeNode<T>[]>;

  constructor(private dataService:DataService, private cd: ChangeDetectorRef) {}

  public onDataChange(event:TreeNode<T>[]):void {
    if (!ValidationService.isNullOrUndefined(this.subject)) {
      this.subject.next(event);
    }
  }


  public markForCheck() {
    this.cd.markForCheck();
  }

  public reset() {
    this.tree = null;
    this.isDataLoaded = false;
    this.markForCheck();
  }
}
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { TreeNode } from './../dto/TreeNode';

import html from './fortune-select.component.html';
import css from './fortune-select.component.css';

@Component({
  selector: 'fortune-select',
  template: html,
  styles: [css],
})

export class FortuneSelectComponent<T> {
  @Input() currentNode:  TreeNode<T>;
  @Input() collapsed:    boolean = false;
  @Input() linked:       boolean = true;
  @Input() searchTerm:   string  = '';
  @Input() singleSelect: boolean = false;
  @Output() dataChanged          = new EventEmitter<TreeNode<T>[]>();

  selectedRadioValue:T;

  public checkboxChangedEvent():void {
    let list:TreeNode<T>[];
    this.currentNode.indeterminate = true;

    if (this.linked) {
      list = TreeNode.getTopLevelCheckedNodes(this.currentNode);
    } else {
      list = TreeNode.getAllCheckedNodes(this.currentNode);
    }

    this.dataChanged.emit(list);
  }

  public radioChangedEvent(event:TreeNode<T>):void {
    this.dataChanged.emit([event]);
  }
}
import{Component,Input,OnInit,ChangeDetectionStrategy,ChangeDetectorRef}来自“@angular/core”;
从“../../shared/service/data.service”导入{DataService};
从“../../shared/dto/TreeNode”导入{TreeNode};
从“./rightside.component.html”导入html;
从“/rightside.component.css”导入css;
@组成部分({
选择器:'右侧组件',
模板:html,
提供者:[数据服务],
样式:[css],
changeDetection:ChangeDetectionStrategy.OnPush
})
导出类RightSideComponent实现OnInit{
选择:字符串[];
@Input()树节点:树节点[];
构造函数(私有cd:ChangeDetectorRef){}
恩戈尼尼特(){
}
getSelections():树节点[]{
if(typeof(this.treeNode)=“undefined”| |(this.treeNode)==null){
返回[];
}
返回这个.treeNode;
}
取消选择(项目:TreeNode):无效{
if((item.children)!==null){
item.children.forEach(元素=>{
取消选择(元素);
});
}
item.selected=false;
}
}
productline.component.html:

<p>Productlines</p>
<mat-input-container>
    <input #searchInput matInput placeholder="Search for Product Line">
</mat-input-container>
<div class="flex-container">
<div class="PLCheck" *ngIf="isDataLoaded">
    <fortune-select
       (dataChanged)="onDataChange($event)"
       [searchTerm]="searchInput.value"
       [currentNode]="tree"
       [singleSelect]="singleSelect"
       [collapsed]="true"></fortune-select>
</div>
<div class="sendToRight">
    <rightside-component
        [treeNode]="selectedProductLine">
    </rightside-component>
</div>
</div>
产品线

Productline.component.ts:

import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { DataService } from '../../shared/service/data.service';
import { TreeNode } from '../../shared/dto/TreeNode';

import html from './rightside.component.html';
import css from './rightside.component.css';

@Component({
  selector: 'rightside-component',
  template: html,
  providers: [DataService],
  styles: [css],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class RightSideComponent implements OnInit {
  selections: string[];
  @Input() treeNode: TreeNode<string>[];

  constructor(private cd: ChangeDetectorRef) {}

  ngOnInit() {
  }

  getSelections() : TreeNode<string>[] {
    if (typeof(this.treeNode) == "undefined" || (this.treeNode) === null) {
      return [];
    }
    return this.treeNode;
  }

  deselect(item: TreeNode<string>): void {
    if((item.children) !== null) {
      item.children.forEach(element => {
        this.deselect(element);
      });
    }
    item.selected = false;
  }

}
import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import * as API from '../../shared/api-routes';
import { DataService } from '../../shared/service/data.service';
import { ValidationService } from '../../shared/service/validation.service';
import { Subject } from 'rxjs/Subject';
import { BasestepComponent } from '../basestep-component/basestep.component';
import { TreeNode } from '../../shared/dto/TreeNode';

import html from './productline.component.html';
import css from './productline.component.css';

@Component({
  selector: 'productline-component',
  template: html,
  providers: [DataService],
  styles: [css],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class ProductlineComponent extends BasestepComponent<string> implements OnInit {
  selectedProductLine:    TreeNode<string>[];

  constructor(dataService:DataService, cd:ChangeDetectorRef) {
    super(dataService, cd);
  }

  ngOnInit() {
    this.subject.subscribe((productline) => this.productLineChange(productline));
  }

  public productLineChange(productLine: TreeNode<string>[]):void {
    this.selectedProductLine = productLine;
  }

}
import { Input, ChangeDetectorRef } from '@angular/core';
import { castTree, ReportTemplate } from '../report-common';
import { DataService } from '../../shared/service/data.service';
import { Subject } from 'rxjs/Subject';
import { ValidationService } from '../../shared/service/validation.service';
import { TreeNode } from '../../shared/dto/TreeNode';

export class BasestepComponent<T> {
  public tree: TreeNode<T>;
  public singleSelect: boolean = false;
  public isDataLoaded: boolean;
  public template: ReportTemplate;
  @Input() templateSubject: Subject<ReportTemplate>;
  @Input() subject: Subject<TreeNode<T>[]>;

  constructor(private dataService:DataService, private cd: ChangeDetectorRef) {}

  public onDataChange(event:TreeNode<T>[]):void {
    if (!ValidationService.isNullOrUndefined(this.subject)) {
      this.subject.next(event);
    }
  }


  public markForCheck() {
    this.cd.markForCheck();
  }

  public reset() {
    this.tree = null;
    this.isDataLoaded = false;
    this.markForCheck();
  }
}
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { TreeNode } from './../dto/TreeNode';

import html from './fortune-select.component.html';
import css from './fortune-select.component.css';

@Component({
  selector: 'fortune-select',
  template: html,
  styles: [css],
})

export class FortuneSelectComponent<T> {
  @Input() currentNode:  TreeNode<T>;
  @Input() collapsed:    boolean = false;
  @Input() linked:       boolean = true;
  @Input() searchTerm:   string  = '';
  @Input() singleSelect: boolean = false;
  @Output() dataChanged          = new EventEmitter<TreeNode<T>[]>();

  selectedRadioValue:T;

  public checkboxChangedEvent():void {
    let list:TreeNode<T>[];
    this.currentNode.indeterminate = true;

    if (this.linked) {
      list = TreeNode.getTopLevelCheckedNodes(this.currentNode);
    } else {
      list = TreeNode.getAllCheckedNodes(this.currentNode);
    }

    this.dataChanged.emit(list);
  }

  public radioChangedEvent(event:TreeNode<T>):void {
    this.dataChanged.emit([event]);
  }
}
import{Component,Input,OnInit,ChangeDetectionStrategy,ChangeDetectorRef}来自“@angular/core”;
从“../../shared/API routes”导入*作为API;
从“../../shared/service/data.service”导入{DataService};
从“../../shared/service/validation.service”导入{ValidationService};
从'rxjs/Subject'导入{Subject};
从“../basestep component/basestep.component”导入{basestepmonent};
从“../../shared/dto/TreeNode”导入{TreeNode};
从“./productline.component.html”导入html;
从“/productline.component.css”导入css;
@组成部分({
选择器:“productline组件”,
模板:html,
提供者:[数据服务],
样式:[css],
changeDetection:ChangeDetectionStrategy.OnPush
})
导出类ProductlineComponent扩展BasestepComponent实现OnInit{
selectedProductLine:TreeNode[];
构造函数(dataService:dataService,cd:ChangeDetectorRef){
超级(数据服务,cd);
}
恩戈尼尼特(){
this.subject.subscribe((productline)=>this.productLineChange(productline));
}
公共产品线更改(产品线:TreeNode[]):无效{
this.selectedProductLine=productLine;
}
}
Basestep.component.ts:

import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { DataService } from '../../shared/service/data.service';
import { TreeNode } from '../../shared/dto/TreeNode';

import html from './rightside.component.html';
import css from './rightside.component.css';

@Component({
  selector: 'rightside-component',
  template: html,
  providers: [DataService],
  styles: [css],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class RightSideComponent implements OnInit {
  selections: string[];
  @Input() treeNode: TreeNode<string>[];

  constructor(private cd: ChangeDetectorRef) {}

  ngOnInit() {
  }

  getSelections() : TreeNode<string>[] {
    if (typeof(this.treeNode) == "undefined" || (this.treeNode) === null) {
      return [];
    }
    return this.treeNode;
  }

  deselect(item: TreeNode<string>): void {
    if((item.children) !== null) {
      item.children.forEach(element => {
        this.deselect(element);
      });
    }
    item.selected = false;
  }

}
import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import * as API from '../../shared/api-routes';
import { DataService } from '../../shared/service/data.service';
import { ValidationService } from '../../shared/service/validation.service';
import { Subject } from 'rxjs/Subject';
import { BasestepComponent } from '../basestep-component/basestep.component';
import { TreeNode } from '../../shared/dto/TreeNode';

import html from './productline.component.html';
import css from './productline.component.css';

@Component({
  selector: 'productline-component',
  template: html,
  providers: [DataService],
  styles: [css],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class ProductlineComponent extends BasestepComponent<string> implements OnInit {
  selectedProductLine:    TreeNode<string>[];

  constructor(dataService:DataService, cd:ChangeDetectorRef) {
    super(dataService, cd);
  }

  ngOnInit() {
    this.subject.subscribe((productline) => this.productLineChange(productline));
  }

  public productLineChange(productLine: TreeNode<string>[]):void {
    this.selectedProductLine = productLine;
  }

}
import { Input, ChangeDetectorRef } from '@angular/core';
import { castTree, ReportTemplate } from '../report-common';
import { DataService } from '../../shared/service/data.service';
import { Subject } from 'rxjs/Subject';
import { ValidationService } from '../../shared/service/validation.service';
import { TreeNode } from '../../shared/dto/TreeNode';

export class BasestepComponent<T> {
  public tree: TreeNode<T>;
  public singleSelect: boolean = false;
  public isDataLoaded: boolean;
  public template: ReportTemplate;
  @Input() templateSubject: Subject<ReportTemplate>;
  @Input() subject: Subject<TreeNode<T>[]>;

  constructor(private dataService:DataService, private cd: ChangeDetectorRef) {}

  public onDataChange(event:TreeNode<T>[]):void {
    if (!ValidationService.isNullOrUndefined(this.subject)) {
      this.subject.next(event);
    }
  }


  public markForCheck() {
    this.cd.markForCheck();
  }

  public reset() {
    this.tree = null;
    this.isDataLoaded = false;
    this.markForCheck();
  }
}
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { TreeNode } from './../dto/TreeNode';

import html from './fortune-select.component.html';
import css from './fortune-select.component.css';

@Component({
  selector: 'fortune-select',
  template: html,
  styles: [css],
})

export class FortuneSelectComponent<T> {
  @Input() currentNode:  TreeNode<T>;
  @Input() collapsed:    boolean = false;
  @Input() linked:       boolean = true;
  @Input() searchTerm:   string  = '';
  @Input() singleSelect: boolean = false;
  @Output() dataChanged          = new EventEmitter<TreeNode<T>[]>();

  selectedRadioValue:T;

  public checkboxChangedEvent():void {
    let list:TreeNode<T>[];
    this.currentNode.indeterminate = true;

    if (this.linked) {
      list = TreeNode.getTopLevelCheckedNodes(this.currentNode);
    } else {
      list = TreeNode.getAllCheckedNodes(this.currentNode);
    }

    this.dataChanged.emit(list);
  }

  public radioChangedEvent(event:TreeNode<T>):void {
    this.dataChanged.emit([event]);
  }
}
从'@angular/core'导入{Input,ChangeDetectorRef};
从“../report common”导入{castTree,ReportTemplate};
从“../../shared/service/data.service”导入{DataService};
从'rxjs/Subject'导入{Subject};
从“../../shared/service/validation.service”导入{ValidationService};
从“../../shared/dto/TreeNode”导入{TreeNode};
导出类BasestepComponent{
公树:树形;
public singleSelect:boolean=false;
公共isDataLoaded:布尔值;
公共模板:ReportTemplate;
@Input()模板主题:主题;
@输入()主题:主题;
构造函数(私有数据服务:数据服务,私有cd:ChangeDetectorRef){}
公共onDataChange(事件:TreeNode[]):无效{
如果(!ValidationService.isNullOrUndefined(this.subject)){
本.主题.下一个(事件);
}
}
公共标记forcheck(){
这个.cd.markForCheck();
}
公共重置(){
this.tree=null;
this.isDataLoaded=false;
这个.markForCheck();
}
}
我希望右侧的顺序与选择项目的顺序一致,而不是基于层次结构。因此,即使A在层次结构中位于B之上,我也希望显示B,然后根据选择显示A

基本上,我希望选择能够按照选择的顺序动态显示

编辑1:

正在为fortune-select.component.ts添加代码:

import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { DataService } from '../../shared/service/data.service';
import { TreeNode } from '../../shared/dto/TreeNode';

import html from './rightside.component.html';
import css from './rightside.component.css';

@Component({
  selector: 'rightside-component',
  template: html,
  providers: [DataService],
  styles: [css],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class RightSideComponent implements OnInit {
  selections: string[];
  @Input() treeNode: TreeNode<string>[];

  constructor(private cd: ChangeDetectorRef) {}

  ngOnInit() {
  }

  getSelections() : TreeNode<string>[] {
    if (typeof(this.treeNode) == "undefined" || (this.treeNode) === null) {
      return [];
    }
    return this.treeNode;
  }

  deselect(item: TreeNode<string>): void {
    if((item.children) !== null) {
      item.children.forEach(element => {
        this.deselect(element);
      });
    }
    item.selected = false;
  }

}
import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import * as API from '../../shared/api-routes';
import { DataService } from '../../shared/service/data.service';
import { ValidationService } from '../../shared/service/validation.service';
import { Subject } from 'rxjs/Subject';
import { BasestepComponent } from '../basestep-component/basestep.component';
import { TreeNode } from '../../shared/dto/TreeNode';

import html from './productline.component.html';
import css from './productline.component.css';

@Component({
  selector: 'productline-component',
  template: html,
  providers: [DataService],
  styles: [css],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class ProductlineComponent extends BasestepComponent<string> implements OnInit {
  selectedProductLine:    TreeNode<string>[];

  constructor(dataService:DataService, cd:ChangeDetectorRef) {
    super(dataService, cd);
  }

  ngOnInit() {
    this.subject.subscribe((productline) => this.productLineChange(productline));
  }

  public productLineChange(productLine: TreeNode<string>[]):void {
    this.selectedProductLine = productLine;
  }

}
import { Input, ChangeDetectorRef } from '@angular/core';
import { castTree, ReportTemplate } from '../report-common';
import { DataService } from '../../shared/service/data.service';
import { Subject } from 'rxjs/Subject';
import { ValidationService } from '../../shared/service/validation.service';
import { TreeNode } from '../../shared/dto/TreeNode';

export class BasestepComponent<T> {
  public tree: TreeNode<T>;
  public singleSelect: boolean = false;
  public isDataLoaded: boolean;
  public template: ReportTemplate;
  @Input() templateSubject: Subject<ReportTemplate>;
  @Input() subject: Subject<TreeNode<T>[]>;

  constructor(private dataService:DataService, private cd: ChangeDetectorRef) {}

  public onDataChange(event:TreeNode<T>[]):void {
    if (!ValidationService.isNullOrUndefined(this.subject)) {
      this.subject.next(event);
    }
  }


  public markForCheck() {
    this.cd.markForCheck();
  }

  public reset() {
    this.tree = null;
    this.isDataLoaded = false;
    this.markForCheck();
  }
}
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { TreeNode } from './../dto/TreeNode';

import html from './fortune-select.component.html';
import css from './fortune-select.component.css';

@Component({
  selector: 'fortune-select',
  template: html,
  styles: [css],
})

export class FortuneSelectComponent<T> {
  @Input() currentNode:  TreeNode<T>;
  @Input() collapsed:    boolean = false;
  @Input() linked:       boolean = true;
  @Input() searchTerm:   string  = '';
  @Input() singleSelect: boolean = false;
  @Output() dataChanged          = new EventEmitter<TreeNode<T>[]>();

  selectedRadioValue:T;

  public checkboxChangedEvent():void {
    let list:TreeNode<T>[];
    this.currentNode.indeterminate = true;

    if (this.linked) {
      list = TreeNode.getTopLevelCheckedNodes(this.currentNode);
    } else {
      list = TreeNode.getAllCheckedNodes(this.currentNode);
    }

    this.dataChanged.emit(list);
  }

  public radioChangedEvent(event:TreeNode<T>):void {
    this.dataChanged.emit([event]);
  }
}
从'@angular/core'导入{Component,Input,Output,EventEmitter};
从“/../dto/TreeNode”导入{TreeNode};
从“/fortune select.component.html”导入html;
从“/fortune select.component.css”导入css;
@组成部分({
选择器:'财富选择',
模板:html,
样式:[css],
})
导出类组件{
@Input()currentNode:TreeNode;
@Input()折叠:boolean=false;
@Input()链接:布尔值=true;
@Input()searchTerm:string='';
@Input()singleSelect:boolean=false;
@Output()dataChanged=neweventemitter();
选择的放射性值:T;
public checkboxChangedEvent():void{
let list:TreeNode[];
this.currentNode.Undeterminate=true;
if(this.linked){
list=TreeNode.getToLevel检查节点(this.currentNode);
}否则{
list=TreeNode.getAllCheckedNodes(this.currentNode);
}
this.dataChanged.emit(列表);
}
公共无线电交换机(事件:TreeNode):无效{
this.dataChanged.emit([event]);
}
}
是否有一种方法可以将每个选择存储在列表中,然后显示列表?这样,它将按顺序显示选择。现在,整个结构正在遍历,因此它按树的顺序显示

有办法做到这一点吗