Angular Pokemon项目点击按钮后随机攻击结果不显示问题修复请求
宝可梦随机攻击生成器显示问题修复
问题
开发宝可梦项目时,点击表单的「Generate random attack!」按钮后,无法显示从选中宝可梦的四个攻击技能中随机生成的技能名称。
现有代码
模板代码(HTML)
<div> <mat-card class="attack-form"> <mat-card-header id="attacks"> <mat-card-title class="h4">Random Attack Generator</mat-card-title> </mat-card-header> <mat-card-content> <form id="form-attacks" [formGroup]="attacksForm" (ngSubmit)="generateRandomAttack()"> <mat-form-field appearance="standard"> <mat-label>Selecciona un entrenador</mat-label> <mat-select matNativeControl formControlName="trainerName" > <mat-option *ngFor="let trainer of trainers" [value]="trainer.fullName"> {{trainer.fullName}} </mat-option> </mat-select> </mat-form-field> <mat-form-field appearance="standard"> <mat-label>Selecciona un pokemon</mat-label> <mat-select matNativeControl formControlName="pokemonName" #matSelect> <mat-option *ngFor="let pokemon of pokemons" [value]="pokemon.name"> {{pokemon.name}} </mat-option> </mat-select> </mat-form-field> <mat-checkbox [checked]="rage == true" formControlName="lifeUnderFifty">Click if life is under 50%</mat-checkbox> <!-- <re-captcha class="re-captcha" formControlName="recaptcha" siteKey="6Lf2lRciAAAAAC6tIMOl7kPrHfv7yUdAGs0VCz_K"></re-captcha> --> <button type="submit" mat-raised-button [disabled]="!attacksForm.valid" >Generate random attack!</button> </form> </mat-card-content> <div class="randomAttack"> <h2>Attack generated</h2> <p>{{ generateRandomAttack() }} </p> </div> </mat-card> </div>
服务层代码(TypeScript)
selectAttack(trainers: Trainer[], chosenTrainer: string, chosedPokemon: string, rage: boolean) { const trainer = trainers.find((trainer: Trainer) => trainer.fullName === chosenTrainer); const pokemon = trainer?.pokemons.find((pkm: Pokemon) => pkm.name === chosedPokemon); if(!pokemon) return undefined; const natureConfig = this.natureDicts.find((nature: NatureDictionaries) => nature.name === pokemon.nature); if (!natureConfig) return undefined; let natureValues; if (rage) { natureValues = { attackValue: natureConfig.rageAttVal, defenseValue: natureConfig.rageDefVal, }; } else { natureValues = { attackValue: natureConfig.basicAttkVal, defenseValue: natureConfig.basicDefVal, }; } const attackStyle = this.getRandomStyleAttack(natureValues); return this.getRandomAttack(pokemon, attackStyle); } getRandomStyleAttack(natureValues: any){ var num=Math.random(); let styleAttack; if(num < natureValues.attackValue) styleAttack = "Attack"; else if(num < (natureValues.attackValue + natureValues.defenseValue)) styleAttack = "Defense"; else styleAttack = "Support"; console.log(styleAttack); return styleAttack; } getRandomAttack(pokemon: Pokemon, styleAttack: string){ var attackList = pokemon.attacks; if(pokemon.attacks.some((atk: any) => atk.style == styleAttack)){ attackList = pokemon.attacks.filter(atk => atk.style == styleAttack); var index = Math.floor(Math.random() * attackList.length-1); }else{ var index = Math.floor(Math.random() * attackList.length-1); } console.log(attackList[index]); return attackList[index].name; }
组件控制器代码(TypeScript)
generateRandomAttack(){ // Proceed with assigning the value to this.randomAttack const attack = this.attackService.selectAttack(this.trainers, this.trainerName, this.pokemonName, this.rage); if (typeof attack === 'string') { this.randomAttack = attack; } return this.randomAttack; }
修复步骤
1. 修正模板中的变量绑定
模板中直接调用generateRandomAttack()会导致Angular变更检测时重复执行函数,且无法正确绑定提交后生成的值。将显示区域的代码改为直接绑定组件变量:
<div class="randomAttack"> <h2>Attack generated</h2> <p>{{ randomAttack }}</p> </div>
同时在组件类中初始化变量:
randomAttack: string = '';
2. 修复组件中表单值的获取逻辑
原代码依赖组件的trainerName、pokemonName、rage变量,但这些变量未与表单控件同步。改为直接从表单中获取值:
generateRandomAttack(){ const formValues = this.attacksForm.value; const chosenTrainer = formValues.trainerName; const chosenPokemon = formValues.pokemonName; const rage = formValues.lifeUnderFifty; const attack = this.attackService.selectAttack(this.trainers, chosenTrainer, chosenPokemon, rage); if (typeof attack === 'string') { this.randomAttack = attack; } }
3. 修复攻击索引计算的错误
getRandomAttack函数中Math.floor(Math.random() * attackList.length-1)会导致当攻击列表长度为1时生成索引-1,引发undefined错误。修正索引计算逻辑:
getRandomAttack(pokemon: Pokemon, styleAttack: string){ let attackList = pokemon.attacks; if(pokemon.attacks.some((atk: any) => atk.style == styleAttack)){ attackList = pokemon.attacks.filter(atk => atk.style == styleAttack); } // 修正索引范围,确保在0到attackList.length-1之间 const index = Math.floor(Math.random() * attackList.length); // 增加空值判断,避免报错 return attackList[index]?.name || '无可用攻击技能'; }
4. (可选)修正服务函数的参数拼写
将selectAttack函数的参数chosedPokemon改为chosenPokemon,保持命名规范:
selectAttack(trainers: Trainer[], chosenTrainer: string, chosenPokemon: string, rage: boolean) { // ... 原有逻辑不变,仅修改参数名 const pokemon = trainer?.pokemons.find((pkm: Pokemon) => pkm.name === chosenPokemon); // ... }
完成以上修改后,点击提交按钮即可正常显示随机生成的攻击技能名称。
内容的提问来源于stack exchange,提问作者Eric Díaz
相关产品推荐
相关产品推荐

