You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:25:14