打字稿类型无法分配给type:重新分配项目时出错

时间:2018-08-13 20:08:56

标签: javascript html angular typescript types

我正在尝试实现以下功能:单击该按钮后,该按钮将其从列表中隐藏,并从左侧的层次结构(TreeNode)中取消选择相应的复选框。

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

}

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>

Treenode.ts:

import { ValidationService } from '../service/validation.service';

export class TreeNode<T> {
  displayName:   string;
  children:      TreeNode<T>[];
  selected:      boolean;
  collapsed?:    boolean;
  indeterminate: boolean;
  selectable:    boolean;
  value:         T;

  public static getAllNodeValues<T>(tree: TreeNode<T>):T[] {
    return TreeNode.getAllCheckedNodes<T>(tree).map((nodes:TreeNode<T>) => nodes.value);
  }

  public static getTopLevelNodeValues<T>(tree: TreeNode<T>):T[] {
    return TreeNode.getTopLevelCheckedNodes<T>(tree).map((nodes:TreeNode<T>) => nodes.value);
  }

  public static getTopLevelCheckedNodes<T>(tree: TreeNode<T>):TreeNode<T>[] {
    if(tree.selected) {
      return [tree];
    } else if(tree.indeterminate) {
      return tree.children.reduce(
        (acc,child) => acc.concat(TreeNode.getTopLevelCheckedNodes(child)),[]);
    } else {
      return <TreeNode<T>[]>[];
    }
  }

  public static getAllCheckedNodes<T>(tree: TreeNode<T>):TreeNode<T>[] {
    if(tree.selected && tree.children) {
      return tree.children.reduce(
        (acc,child) => acc.concat(TreeNode.getAllCheckedNodes(child)),[tree]);
    } else if (tree.selected) {
      return [tree];
    } else if(tree.children) {
      return tree.children.reduce(
        (acc,child) => acc.concat(TreeNode.getAllCheckedNodes(child)),[]);
    } else {
      return <TreeNode<T>[]>[];
    }
  }

  public getValue(): T {
    return this.value;
  }

  public matches(searchTerm:string):boolean {
    if(this.displayName.toLowerCase().includes(searchTerm.toLowerCase())) {
      return true;
    }
    if (!ValidationService.isEmptyList(this.children)) {
      return this.children.some((child) => child.matches(searchTerm));
    }
    return false;
  }

  public selectChildren(selected:boolean):void {
    if (!ValidationService.isEmptyList(this.children)) {
      this.children.map((child) => {
        child.selected = selected;
        child.indeterminate = false;
        child.selectChildren(selected);
      });
    }
  }
}

我面临的问题:

当我单击任何一个按钮进行隐藏时,我必须多次单击(也在屏幕的另一部分),然后隐藏它。但是,如果我从最底部的按钮开始并转到顶部,则只需单击一下即可使用。

为了解决这个问题,我尝试通过更改以下内容来重新分配项目:

item.selected = false;

item = {...item, selected: false};

但是,我得到了错误:

类型'{已选择:否; displayName:字符串;子代:TreeNode [];崩溃了?:布尔值; indete ...”不能分配给“ TreeNode”类型。类型'{selected:false;中缺少属性'getValue'。 displayName:字符串;子代:TreeNode [];崩溃了?:布尔值;确实...”。

有没有办法解决?即使按任意顺序单击,如何隐藏按钮也可以单击以使用?

编辑1:

children : (5) [{…}, {…}, {…}, {…}, {…}]
collapsed : true
displayName : "Consumer - A1"
getValue : ƒ ()
indeterminate : false
matches : ƒ (searchTerm)
selectChildren : ƒ (selected)
selectable : true
selected : true
value : "A1"

在json上方展开子级时(层次结构中有5个子节点):

0:{value: "A2", displayName: "Con - A2", selectable: true, selected: true, children: Array(3), …}
1:{value: "A3", displayName: "H - A3", selectable: true, selected: true, children: Array(2), …}
2:{value: "A4", displayName: "Phy - A4", selectable: true, selected: true, children: Array(4), …}
3:{value: "A5", displayName: "S - A5", selectable: true, selected: true, children: Array(6), …}
4:{value: "0000", displayName: "Unspecified - 0000", selectable: true, selected: true, children: Array(0), …}

这些节点还具有子节点。

编辑2:

当我从以下位置修改css时,它将起作用:

.selection-list {
  list-style: none;
  margin-top: 5px;
  margin-bottom: 10px;
  line-height: 15px;
  font-size: 30px;
  color: #555;
  padding-left: 23px;
  text-transform: capitalize;
}

.selection-list {
  list-style: none;
  margin-top: 5px;
  margin-bottom: 10px;
  line-height: 15px;
  color: #555;
  padding-left: 23px;
  text-transform: capitalize;
}

“ font-size”标签以某种方式引起了问题。关于其背后原因的任何输入是什么?

0 个答案:

没有答案