角度组件注入问题



我目前在使用角度组件注入原理时遇到问题。我有一个标题组件,必须在另一个我称为WelcomePage组件时使用。我的目标是标头组件可以使用其父组件的方法和属性。为此,我创建了以下抽象类:

export abstract class WelcomeInterface {
default: any;
languagesSorted: any;
/**
* Change app language
* @param langSelect language choice
*/
abstract onChangeLang(langSelect: string): void;
}

然后 WelcomePage 类实现 WelcomeInterface。我还向父组件添加了一个提供程序,以允许 Header 在注入后使用这些方法。

这是欢迎页面组件

@Component({
selector: 'app-welcome-page',
templateUrl: './welcomePage.component.html',
providers: [{ provide: WelcomeInterface, useClass: forwardRef(() => WelcomePageComponent) }]
})
/**
* *summary
*
* *summay
*/
export class WelcomePageComponent  implements OnInit, OnDestroy, WelcomeInterface {
getPaySubscription: Subscription;
default: { value: string, flag: string };
languages = new Array<{ value: string, flag: string }>();
languagesSorted = new Array<{ value: string, flag: string }>();
isClosed: boolean;
loading: boolean;
urlJson = './assets/i18n/languages.json';
paymentMode: string;
orderId: any;
image: string;
paymentModeConstants = AppConstants.paymentModes;
routerEventSubscription: Subscription;
navEventSubscription: Subscription;
………

我遇到的问题是标题组件在其生命周期中根本看不到 WelcomePage 属性的更新。 这会导致我的应用程序中出现完全显示错误。

这就是我编写标头组件的方式

import { Component, OnInit, Input, Optional } from '@angular/core';
import { WelcomeInterface } from 'src/app/models/welcomeInterface';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
constructor(@Optional() public welcomePage: WelcomeInterface) {
}
ngOnInit() {
}
}

在我的标题组件的视图下方

<header class="header bluegreengradient">
<div *ngIf="welcomePage" class="control has-icons-left is-right">
<!-- can display if src= appConfig.settings.appLogo -->
<div class="select is-small">
<select #langSelect (change)="welcomePage.onChangeLang(langSelect.value)">
<option *ngFor="let lang of welcomePage.languagesSorted">{{lang.value}}</option>
</select>
<div class="icon is-small is-left">
<i class="flag-icon flag-icon-{{ welcomePage.default?     welcomePage.default.flag:'earth'}}"></i>
</div>
</div>
</div>
<div class="container">
<h1 *ngIf="welcomePage" class="heading1">
<!-- create img source, add h1 can display if src= appConfig.settings.appLogo -->
<figure><img alt="logo" [src]="imageSrc"></figure>
</h1>
<h2 id="welcome-message" class="heading2 is-uppercase">
<!-- replace by headerTitle-->
{{ headerText | translate}}
</h2>
</div>
</header>

您的问题是您使用useClassDI 提供程序的配方,而应该使用useExisting.

如果出现useClass则创建一个与角度视图树没有连接的新实例。

useExisting键可确保子组件将获取父组件的真实现有实例。

providers: [{ provide: Interface, useExisting: forwardRef(() => AppComponent) }]
^^^^^^^^^^^
take current instance of AppComponent

堆栈闪电战示例

要解决您的问题,您需要将 useClass 更改为 use存在 像这样。

providers: [{ provide: WelcomeInterface, useExisting: forwardRef(() => WelcomePageComponent) }]

在此处查看堆栈闪电战以获取概念验证。这是因为使用 use 类时,您可以为子对象提供一个新对象而不是父对象。

这不是在角度组件之间实现双向通信的正确方法。您应该使用@Input@output来实现此目的。

import { Component, OnInit, Input, Optional } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
@Input() languages: [];    
@Output() valueChange = new EventEmitter();
constructor() {
}
ngOnInit() {
}
onSelectChange(value) {
this.valueChange.emit(value);
}
}

在您的父组件中

<app-header [languages]="sortedLanguages" (valueChange)="onChangeLang($event)"><app-header>

你的代码是错误的。

为了传达两个组件,您应该使用:

@Input将数据从父级传递到子级,并且

@Output触发从子项到父项的事件

如果您不想向组件注入某些服务,可以遵循以下语法:

@Injectable()
export class MyService { ... }

并将其注入到您的组件中,如下所示:

@Component({
...
})
export class MyComponent {
...
constructor(private myService: MyService)
}

PS:如果"我的组件"有一个模块,你也必须把你的服务放在那里,例如:

@NgModule({
...
declarations: [MyComponent],
providers: [MyService}
})
export class MyModule { }

最新更新