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
相关产品推荐
相关产品推荐

