首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从子项到父项的更改检测

从子项到父项的更改检测
EN

Stack Overflow用户
提问于 2018-08-07 06:21:09
回答 2查看 96关注 0票数 1

我正在尝试在我的UI中启用功能,该功能将在选择/取消选择时动态显示选择。

代码语言:javascript
复制
import { Wizard } from './report-common';
import { Router } from '@angular/router';
import { DataService } from './../shared/service/data.service';
import { TreeNode } from './../shared/dto/TreeNode';
import { Component, OnInit } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import 'rxjs/Rx';
import * as STEPS from '../shared/constants';

import html from './report-builder.component.html';
import css from './report-builder.component.css';

@Component({
  selector: 'report-builder',
  template: html,
  providers: [DataService],
  styles: [css]
})

export class ReportBuilderComponent implements OnInit {
  selectedProductLine:    TreeNode<string>[];
  rightside:              Wizard  = new Wizard([STEPS.PRODUCT_LINE]);
  productLineSubject              = new Subject<TreeNode<string>[]>();
  //this allows the html to access the constants
  HTML_STEPS                      = STEPS;

  constructor (private dataService: DataService, private router: Router) {}

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

  public productLineChange(productLine: TreeNode<string>[]):void {
    this.selectedProductLine = productLine;
    this.rightside.setSelection(this.extractDisplayNames(productLine), STEPS.PRODUCT_LINE);
  }

  private extractDisplayNames <T>(nodes: TreeNode<T>[]): string[] {
    return nodes.map(node => node.displayName);
  }

}

html相关代码:

代码语言:javascript
复制
<div *ngFor="let step of rightside.steps">
  <li *ngIf="!step.hidden">
    <rightside-component class="side-button" [selectionSubject]="step.selections">
    </rightside-component>
  </li>
</div>

"Wizard“结构如下:(report-common.ts)

代码语言:javascript
复制
import { DataService } from './../shared/service/data.service';
import { TreeNode } from './../shared/dto/TreeNode';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

export class WizardStep {
  selections: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);

}

export class Wizard {
  currentComponent:WizardStep;
  steps:WizardStep[];

  public setSelection(selections:any[], component:string) {
    let componentStep = this.steps.find(step => step.component === component);
    if(!componentStep) { return; }
    componentStep.selections.next(selections);
  }

}

Rightside-component.ts:

代码语言:javascript
复制
export class RightSideComponent implements OnInit {
  selections: string[];
  @Input() selectionSubject: BehaviorSubject<string[]>;

  constructor(private cd: ChangeDetectorRef) {}

  ngOnInit() {
    this.selectionSubject.subscribe((selections) => {
        this.selections = selections;
        this.cd.detectChanges();
      });
  }
}

Rightside.component.html:

代码语言:javascript
复制
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

<div>
  <ul class="selection-list">
    <li *ngFor="let item of selections">
      <button class="btn">
        <i class="fa fa-close">
          {{item}}
        </i>
      </button>
    </li>
  </ul>
</div>

在这里,我在列表中的每一项前面都添加了一个删除图标。每当单击该按钮时,不仅该项目应该从列表中消失,而且应该从正在更改它的原始结构中取消选择。

我尝试在这里使用更改检测,但没有像预期的那样工作。

我基本上想使用Angular 5为我的数据结构做一些类似于这个http://next.plnkr.co/edit/1Fr83XHkY0bWd9IzOwuT?p=preview&utm_source=legacy&utm_medium=worker&utm_campaign=next&preview的事情。任何关于如何从这一点继续前进的想法都将不胜感激。如果需要任何额外的代码,请让我知道。

EN

回答 2

Stack Overflow用户

发布于 2018-08-07 08:44:39

这很容易做到。只使用Pipe,这将是交易。

首先,在显示列表(如Rightside.component.html)中,您没有创建指定的选项。使用filter out取消选择项目。最后,您可以设置选定的,它将显示为动态。

Rightside.component.html

代码语言:javascript
复制
<div>
  <ul class="selection-list">
    <li *ngFor="let item of STEP | unselect_filter">
     <!-- I couldn't found your data list , so let STEP instead. -->
      <button class="btn">
        <i class="fa fa-close">
          {{item}}
        </i>
      </button>
    </li>
  </ul>
</div>

filter.pipe.ts

代码语言:javascript
复制
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'unselect_filter'
})
export class MyFilterPipe implements PipeTransform {
    transform(items: any[], filter: Object): any {
        return items.filter(item => !item.select);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2018-08-09 13:54:54

代码语言:javascript
复制
I think your object structure of **rightside.steps** is like this

[{
'selections':['xyz','abc'],
....
},
{
'selections':['shm','bsm'],
....
}];

by changing the object structure to the following

[{
'selections':[{
'isSelected': true,
'name':'xyz'
},{
'isSelected': true,
'name':'abc'
}],
....
},
{
'selections':[{
'isSelected': true,
'name':'shm'
},{
'isSelected': true,
'name':'bsm'
}],
....
}]

you can show/hide on the list

<div>
  <ul class="selection-list">
    <li *ngFor="let item of selections" [hidden]="!item.isSelected">
      <button class="btn" (click)="removeItem(item)">
        <i class="fa fa-close">
          {{item}}
        </i>
      </button>
    </li>
  </ul>
</div>

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

  constructor(private cd: ChangeDetectorRef) {}
   @Output() unSelectItem= new EventEmitter<any>();

    removeItem(item) {
      item.isSelected = false;
      this.unSelectItem.emit(item);
    }
}

*ReportBuilderComponent html*

<div *ngFor="let step of rightside.steps">
  <li *ngIf="!step.hidden">
    <rightside-component (unSelectItem)="unSelectItem(item)" class="side-button" [selectionSubject]="step.selections">
    </rightside-component>
  </li>
</div>

export class ReportBuilderComponent implements OnInit {
  // Your existing code

  unSelectItem(item){
   for(var step of rightside.steps){
      for(var selectionItem of step.selections){
        if(selectionItem === item){
           selectionItem.isSelected = false;
        }
    }
   }
  }


}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51716388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档