Тральщик - Angular - PullRequest
       1

Тральщик - Angular

0 голосов
/ 18 февраля 2020

Я делаю angular версию 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[] = []) показано, что это бомба на самом деле?

Я переходя от ванили к angular, может я неправильно создал поля в компоненте платы?

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Я думаю, что лучшим решением было бы создание модели для вашего поля, например:

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

Теперь в вашем BoardComponent вы просто создадите объекты FieldModel и поместите их sh в список полей.

В шаблоне BoardComponent вы должны создать FieldComponent с помощью декларативного подхода в *ngFor, перебирая FieldModels и передавая их в качестве входных свойств вашему 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 предлагает вам доступ к экземпляру компонента.

0 голосов
/ 18 февраля 2020

Я справился с этим, «сопоставив» мой fieldList с fieldComponent следующим образом:

Компонент поля:

@Input() isBomb: boolean;

А затем в шаблоне компонента платы:

<div [className]="'board'">
<app-pool *ngFor="let field of fieldList" [isBomb]="field.isBomb"></app-pool>
</div>

Это делает работу, но я не думаю, что это лучший способ сделать это в Angular.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...