我正在制作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[] = [])
的一般字段列表中显示实际上是炸弹?
我正在从香草转向有角,也许我没有在电路板组件中正确创建字段?
我已经通过将我的fieldList映射到fieldComponent来进行管理,如下所示:
字段组件:
@Input() isBomb: boolean;
然后在板级组件模板中:
<div [className]="'board'">
<app-pool *ngFor="let field of fieldList" [isBomb]="field.isBomb"></app-pool>
</div>
它正在做这项工作,但是我不认为这是在Angular中做这件事的最佳方法。
[如果要动态创建组件,就像要将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
使您可以访问组件实例。