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

Angular 9中Identifier 'world'与'server'未定义问题求助

解决Angular 9中Manager组件无法访问world和server的问题

你遇到的错误本质是Angular组件的作用域隔离导致的:AppComponent里定义的world和server是它自身的属性,ManagerComponent作为子组件,无法直接访问父组件的上下文变量,必须通过@Input装饰器显式接收这些值。

下面是具体的修复步骤:

1. 在ManagerComponent中添加需要的@Input属性

打开manager.component.ts,在类中添加world和server的输入属性,同时优化一下hireManager方法的逻辑避免潜在问题:

import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { World, Pallier } from '../world';

@Component({
  selector: 'app-manager',
  templateUrl: './manager.component.html',
  styleUrls: ['./manager.component.css']
})
export class ManagerComponent implements OnInit {
  canclose=false;
  @Input() manager: Pallier[];
  // 添加以下两个@Input属性,接收父组件传递的值
  @Input() world: World; 
  @Input() server: string; 
  @Output() closemodalevent = new EventEmitter<void>();
  
  constructor() { }

  ngOnInit(): void {
  }

  hireManager(manager : Pallier){
    // 用可选链操作符避免world未加载时的空值报错
    if (this.world?.money >= manager.seuil) {
      alert(`${manager.name} has been hired`);
      this.world.money -= manager.seuil;
      // 找到对应manager并标记为已解锁
      const managerIndex = this.world.managers.pallier.indexOf(manager);
      if(managerIndex !== -1) {
        this.world.managers.pallier[managerIndex].unlocked = true;
      }
      // 找到对应产品并标记manager已解锁
      const targetProduct = this.world.products.product.find(p => p.id === manager.idcible);
      if(targetProduct) {
        targetProduct.managerUnlocked = true;
      }
    } else {
      alert("Not enough money to hire this manager!");
    }
  }

  closemodal(){
    console.log(this.canclose);
    if(this.canclose){
      this.closemodalevent.emit();
    }else{
      this.canclose=true;
    }
  }
}

2. 在父组件模板中传递world和server给子组件

修改app.component.html里的<app-manager>标签,添加[world]和[server]的属性绑定:

<button mat-raised-button id="Upgrade" (click)="modal='Managers'">Managers</button>
<app-manager 
  *ngIf="modal=='Managers'" 
  (closemodalevent)="modal=null" 
  [manager]="world.managers.pallier"
  [world]="world"  <!-- 传递world对象给子组件 -->
  [server]="server" <!-- 传递server地址给子组件 -->
></app-manager>

3. 修正Manager组件模板的变量引用

现在manager.component.html里的world和server就可以正常访问了,同时可以优化*ngFor的遍历源(直接用已接收的manager数组):

<div class="Modal" (clickOutside)="closemodal()">
  <div><h1 class="ManagerTitle">Managers make you feel better !</h1></div>
  <div>
    <div *ngFor="let manager of manager">
      <div *ngIf="!manager.unlocked" class="ManagerLayout">
        <div>
          <div class="logo"><img class="LogoImage" [attr.src]="server+manager.logo"></div>
        </div>
        <div>
          <div class="ManagerName">{{manager.name}}</div>
          <div class="ManagerCible">{{world.products.product[manager.idcible-1].name}}</div>
        </div>
        <div class="ManagerCost">{{manager.seuil}}</div>
      </div>
      <button 
        mat-raised-button 
        id="HireButton" 
        (click)="hireManager(manager)" 
        [ngClass]="{'selectable': (world?.money >= manager.seuil)}"
      > 
        Hire !
      </button>
    </div>
  </div>
</div>

核心原因解释

Angular中每个组件都有独立的组件上下文,父组件的属性不会自动共享给子组件。只有通过@Input装饰器声明的属性,才能从父组件接收数据,子组件的模板和类才能合法访问这些属性。你之前的错误就是因为子组件没有声明这两个输入属性,所以Angular无法在组件上下文中找到对应的变量。

内容的提问来源于stack exchange,提问作者Tameiki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 09:02:40