我在页面上有一个Angular Reactive Form,并且某些Angular函数在 br 页面下约一半后停止工作。我的 mat-card-title 不再显示,并且* ngFor循环不再显示数据。如果我将* ngFor循环到页面上(在 br 之后的 mat-card 之前的任何位置),它就可以正常工作。
我尝试在 br 下面的每个部分中放置一个简单的 li * ngFor = .... ,它在任何地方都无效。我有几个要遍历的数组-它们都不起作用。我在控制台中遇到的唯一错误是“无法读取未定义的属性'includes'”-因为第一个ngFor循环(factionGAs)未填充。我实际上看到它保留了四个插槽(数组中有四个项),但是没有将数据放入其中。
HTML:
<div id="uploader" class="uploader">
<div [hidden]="submitted" class="card-body">
<mat-card id="heading" ([ngModel])="playerSub">
<h3>Entering Results as:</h3>
<h4>{{player.username}}</h4>
</mat-card>
<br>
<mat-card>
<mat-card-title>Find opponent:</mat-card-title>
<form [formGroup]="searchForm" (ngSubmit)="findPlayers()">
<div class="form-group">
<select placeholder="Search by:" class="form-control"
formControlName="searchBy">
<option [value]="null">Search by:</option>
<option value="playerId">Player ID</option>
<option value="email">Email address</option>
<option value="username">Username</option>
</select>
<input *ngIf="searchQuery.includes('playerId')" class="form-
control" type="text"
placeholder="Enter Player ID" formControlName="playerId" />
<input *ngIf="searchQuery.includes('email')" class="form-control"
type="text"
placeholder="Enter Email" formControlName="email" />
<input *ngIf="searchQuery.includes('username')" class="form-
control" type="text" placeholder="Enter Username"
formControlName="username"/>
</div>
<mat-card-actions>
<button class="btn btn-primary" type="submit">Search</button>
</mat-card-actions>
</form>
<mat-card-footer *ngIf="playerList" ([ngModel])="playerList">
{{playerList.username}}</mat-card-footer>
</mat-card>
<br>
<mat-card *ngIf="playerFound" style="text-align: center">
<mat-card-title>Enter your results: </mat-card-title>
<form [formGroup]="uploadForm" (ngSubmit)="submitGame()">
<mat-card-content>
<div class="card-group" style="margin: auto 10% auto 10%">
<mat-card>
<mat-card-title>{{player.username}}'s Results:</mat-card-title>
<div class="form-group">
<select class="form-control" formControlName="P1GA">
<option [ngValue]="null" disabled>Select Grand Alliance:
</option>
<option *ngFor="let ga of factionGAs" value="ga.value">
{{ga.name}}</option>
</select>
<select *ngIf="P1GA.name.includes('Order')"
formControlName="playerOneFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of orderFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P1GA.name.includes('Destruction')"
formControlName="playerOneFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of desFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P1GA.name.includes('Chaos')"
formControlName="playerOneFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of chaosFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P1GA.name.includes('Death')"
formControlName="playerOneFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of deathFactions" [value]="sf">{{sf}}
</option>
</select>
<select class="form-control" formControlName="playerOneResult"
required>
<option [ngValue]="null">Select your result:</option>
<option *ngFor="let result of results" [value]="result">
{{result}}</option>
</select>
</div>
</mat-card>
<mat-card ([ngModel])="playerList">
<mat-card-title>{{playerList.username}}'s Results:</mat-card-title>
<div class="form-group">
<select placeholder="Select Grand Alliance" class="form-control"
formControlName="P2GA">
<option [ngValue]="null">Select Grand Alliance:</option>
<option *ngFor="let ga of factionGAs" [value]="ga">{{ga.name}}
</option>
</select>
<select *ngIf="P2GA.name.includes('Order')"
formControlName="playerTwoFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of orderFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P2GA.name.includes('Destruction')"
formControlName="playerTwoFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of desFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P2GA.name.includes('Chaos')"
formControlName="playerTwoFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of chaosFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P2GA.name.includes('Death')"
formControlName="playerTwoFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of deathFactions" [value]="sf">{{sf}}
</option>
</select>
<select class="form-control" formControlName="playerTwoResult"
required>
<option [ngValue]="null">Select your result:</option>
<option *ngFor="let result of results" [value]="result">
{{result}}</option>
</select>
</div>
</mat-card>
</div>
<mat-card style="align-content: center" width="60%">
<div class="form-group">
<select formControlName="battlePlan" class="form-control"
required>
<option [value]="null">Select Battleplan:</option>
<option *ngFor="let plan of battleplans" [value]="plan">
{{plan}}</option>
</select>
<select class="form-control" formControlName="pointsLevel"
required>
<option [value]="null">Select points level:</option>
<option value="1000">1000</option>
<option value="2000">2000</option>
</select>
</div>
</mat-card>
</mat-card-content>
<br>
<mat-card-actions>
<button type="submit" class="button">Submit</button>
<button class="button" (click)="toggleEditForm()">{{ editBtnText }}
</button>
<input type="button" name="Review" value="History">
</mat-card-actions>
</form>
</mat-card>
</div>
<br>
<mat-card *ngIf="submitted" ([ngModel])="formSub">
<mat-card-title>You submitted the following:</mat-card-title>
<div class="row">
<div class="col-xs-3">Faction: </div>
<div class="col-xs-9">{{formSub.playerOneFaction}}</div>
</div>
<div class="row">
<div class="col-xs-3">Battleplan: </div>
<div class="col-xs-9">{{formSub.battlePlan}}</div>
</div>
<div class="row">
<div class="col-xs-3">Result: </div>
<div class="col-xs-9">{{formSub.playerOneResult}}</div>
</div>
<br>
<mat-card-actions>
<button class="button" (click)="submitted=false">Edit</button>
</mat-card-actions>
</mat-card>
</div>
ts文件:
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { AuthService } from '@/_services/authentication.service';
import { FormBuilder, Validators, FormGroup, FormControl } from
'@angular/forms';
import { Router, ActivatedRoute } from '@angular/router'
import { Games } from '@/_services/games.service';
import { Rank } from '@/_services/rank.service';
import { Game } from '@/_models/games';
import { Player } from '@/_models/players';
import { Subscription, Observable } from 'rxjs';
import { FilterSortService } from '@/_services/filter-sort.service';
import { OrderFactions, DesFactions,
ChaosFactions, DeathFactions, BattlePlans } from '@/_models/data-
arrays';
@Component({
selector: 'app-upload',
templateUrl: './upload.component.html',
styleUrls: ['./upload.component.css']
})
export class UploadComponent implements OnInit, OnDestroy {
@Input() gameId: number;
showEditForm = false;
editBtnText: string;
playerGame: Game;
gamesSub: Subscription;
loggedInSub: Subscription;
routeSub: Subscription;
playerSub: Subscription;
games: Game[];
id: number;
playerOne: number;
playerTwo: number;
player: Player = new Player;
gameCheck: Game = new Game;
playerListSub: Subscription
searchQuery: string[] = [];
playerList: Player = new Player;
playerFound = true;
filteredPlayers: Player[];
factionGAs = [
{ name: 'Chaos', value: 'chaosRank' },
{ name: 'Death', value: 'deathRank' },
{ name: 'Destruction', value: 'desRank' },
{ name: 'Order', value: 'orderRank' }
]
P1GA: string[] = [];
P2GA: string[] = [];
orderFactions = OrderFactions;
chaosFactions = ChaosFactions;
desFactions = DesFactions;
deathFactions = DeathFactions;
battleplans = BattlePlans;
results = [
'Major Victory', 'Minor Victory',
'Minor Loss', 'Major Loss', 'Draw'
]
players: Player[];
loading: boolean;
error: boolean;
query: '';
submitted = false;
searchForm: FormGroup;
uploadForm: FormGroup;
formSub: Subscription;
message: string;
constructor(private router: Router, public auth: AuthService, public game:
Games,
private rank: Rank, public fs: FilterSortService, private
route: ActivatedRoute,
private formBuilder: FormBuilder) { }
ngOnInit() {
this._getGames();
this.toggleEditForm(false);
this._getPlayerList();
this.loggedInSub = this.auth.currentUser.subscribe(loggedIn => {
this.loading = true;
if (loggedIn) {
this._routeSubs();
}
});
this.searchForm = this.formBuilder.group({
searchBy: null,
playerId: null,
email: null,
username: null
});
this.uploadForm = this.formBuilder.group({
playerOne: null,
playerTwo: null,
playerOneResult: [null, Validators.required],
playerTwoResult: [null, Validators.required],
battlePlan: [null, Validators.required],
pointsLevel: [null, Validators.required],
P1GA: null,
P2GA: null,
playerOneFaction: [null, Validators.required],
playerTwoFaction: [null, Validators.required],
playerOneList: [null, Validators.required],
playerTwoList: [null, Validators.required]
});
this.uploadForm.get('P1GA').valueChanges.subscribe(value => {
this.P1GA = [];
this.P1GA.push(value);
});
this.uploadForm.get('P2GA').valueChanges.subscribe(value => {
this.P2GA = [];
this.P2GA.push(value);
});
this.searchForm.get('searchBy').valueChanges.subscribe(value => {
this.searchQuery = [];
this.searchQuery.push(value);
})
}
private _routeSubs() {
// set playerId from route params and subscribe
this.routeSub = this.route.params.subscribe(params => {
this.id = params['playerId'];
this._getPlayer();
});
}
private _getPlayer() {
this.loading = true;
// Get player by playerID
this.playerSub = this.rank.getPlayer(this.id).subscribe(res =>{
this.player = res;
this.loading = false;
},
err => {
console.error(err);
this.loading = false;
this.error = true;
});
}
toggleEditForm(setVal?: boolean) {
this.showEditForm = setVal !== undefined ? setVal : !this.showEditForm;
this.editBtnText = this.showEditForm ? 'Cancel Edit' : 'Edit Last Game';
}
private _getGames() {
this.loading = true;
this.gamesSub = this.game.getGame(this.gameId)
.subscribe(res => {
this.games = res;
this.loading = false;
},
err => {
console.error(err);
this.loading = false;
this.error = true;
});
}
private _getPlayerList() {
this.loading = true;
// Get future, public events
this.playerListSub = this.rank
.getPlayers()
.subscribe(
res => {
this.playerList = res;
this.filteredPlayers = res;
this.loading = false;
},
err => {
console.error(err);
this.loading = false;
this.error = true;
}
);
}
get s() {return this.searchForm.controls;}
findPlayers() {
if (this.searchForm.invalid) {
return;
}
let formValue = this.searchForm.value;
for (let prop in formValue) {
if (!formValue[prop]) {
delete formValue[prop];
}
if (formValue.searchBy) {
delete formValue.searchBy;
}
if (Array.isArray(formValue[prop])) {
let resultArray = formValue[prop].filter((item: any) => item);
if (resultArray.length > 0 ) {
formValue[prop] = resultArray;
}
}
}
this.rank.findPlayer(formValue)
.subscribe(
result => {
this.playerList = result;
console.log(result);
this.playerFound = true;
},
error => {
console.log("Error", error);
});
}
submitGame() {
this.uploadForm.controls['playerOne'].setValue(this.player.playerId);
this.uploadForm.controls['playerTwo'].setValue(this.playerList.playerId);
//console.log(this.uploadForm.value);
this.game.upload(this.uploadForm.value)
.subscribe();
this.submitted = true;
this.formSub = this.uploadForm.value;
}
onSubmitGame(e: any) {
if (e.game) {
this.playerGame = e.game;
this.toggleEditForm(false);
}}
ngOnDestroy() {
this.playerListSub.unsubscribe();
this.gamesSub.unsubscribe();
this.playerSub.unsubscribe();
}
}