我正在制作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
可让您访问组件实例。