我正在制作MineSweeper的有角度版本,但是事件有问题。我的意思是,我的现场组件是这样的:

import {Component, Input, OnInit} from '@angular/core';
import {style} from '@angular/animations';

@Component({
  selector: 'app-pool',
  templateUrl: './field.component.html',
  styleUrls: ['./field.component.sass']
})

export class FieldComponent implements OnInit {
  isBomb = false;
  isInfo = false;
  isClickable = true;
  touchesBombCount = 0;
  isMarkedAsBomb = false;
  isExpanded = false;
  poolID: number;
  isBombExpanded = false;

  @Input() display: string;

  constructor() {
  }

  ngOnInit() {
  }

  expandMe() {
    this.isExpanded = !this.isExpanded;
    if (this.isBomb && this.isExpanded) {
      this.isBombExpanded = !this.isBombExpanded;
    }
    console.log(this);
  }

  onFieldClick(event: any) {
    this.expandMe();
    this.isClickable = false;
    console.log(event);
  }

  onRightClick(event: any) {
    event.preventDefault();
    this.isMarkedAsBomb = !this.isMarkedAsBomb;
  }

}


然后,我在电路板组件中创建字段:

import {Component, Input, OnInit} from '@angular/core';
import {FieldComponent} from '../field/field.component';

@Component({
  selector: 'app-board',
  templateUrl: './board.component.html',
  styleUrls: ['./board.component.sass']
})
export class BoardComponent implements OnInit {
  fieldList: FieldComponent[] = [];
  bombCount: number = 10;
  poolBombList: FieldComponent[] = [];
  private allBombsPlanted = false;
  isGameOver = false;

  @Input() poolCount: number;

  constructor() {
  }

  ngOnInit() {
    this.createBoardFromPools();
    while (!this.allBombsPlanted) {
      this.plantTheBombs();
    }
    console.log(this);
  }

  createBoardFromPools() {
    for (let i = 0; i < this.poolCount; i++) {
      const pool = new FieldComponent();
      pool.poolID = i;
      this.fieldList.push(pool);
    }
  }

  plantTheBombs() {
    const poolCount = this.fieldList.length - 1;
    const poolToPlant = Math.floor((Math.random() * poolCount));
    if (!this.checkIfHasBomb(poolToPlant)) {
      this.poolBombList.push(this.fieldList[poolToPlant]);
      this.fieldList[poolToPlant].isBomb = true;
    }
    if (this.poolBombList.length === this.bombCount) {
      this.allBombsPlanted = true;
    }
  }

  checkIfHasBomb(poolToPlant): boolean {

    for (let i = 0, iMax = this.poolBombList.length; i < iMax; i++) {
      if (this.poolBombList[i].poolID === poolToPlant.poolID) {
        return true;
      }
    }
    return false;
  }

}


我的问题是:

为什么当我在字段的console.log (this)中将炸弹标记为false,甚至在我在board component ( fieldList: FieldComponent[] = [])的一般字段列表中显示实际上是炸弹的时候?

我正在从香草转向有角,也许我没有在木板组件中正确创建字段?

最佳答案

我认为更好的解决方案是为您的Field创建一个模型,例如:

export interface FieldModel{
  poolID: number;
  isBomb:boolean;
  isInfo:boolean;
  isClickable:boolean;
  touchesBombCount:boolean;
  isMarkedAsBomb:boolean;
  isExpanded:boolean;
  isBombExpanded:boolean;
}



现在,在您的BoardComponent中,您只需创建FieldModel对象并将其推入字段列表即可。

在BoardComponent模板中,您可以通过声明方法在*ngFor中创建FieldComponent,该方法在FieldModel上进行迭代,并将它们作为输入属性传递给FieldComponent。

其他解决方案

如果要动态创建组件,例如将FieldComponent放在BoardComponent内,则应使用
ComponentFactory。您还需要一个ViewContainerRef,您的组件可以在其中呈现。

在BoardComponent的模板中,您需要用于字段的一些容器:

<ng-template #boardContainer></ng-template>


在BoardComponent中,您需要借助ViewChild装饰器来获取容器,并注入ComponentFactoryResolver:

export class BoardComponent implements OnInit {
  ...
  @ViewChild('boardContainer',{read:ViewContainerRef,static:false}) boardContainer:ViewContainerRef;

  constructor(private componentFactoryResolver:ComponentFactoryResolver) {
  }
  ...
}


现在,您可以创建如下所示的FieldComponents:

createFieldComponent(){
 const componentFactory = this.componentFactoryResolver.resolveComponentFactory(FieldComponent);
 const componentRef:ComponentRef<FieldComponent> = this.boardContainer.createComponent(componentFactory);
}


然后,componentRef可让您访问组件实例。

10-07 17:27