#javascript #angular #typescript #angular-reactive-forms #angular9
#javascript #angular #typescript #angular-reactive-forms #angular9
Вопрос:
У меня есть приложение, в котором мое требование заключается в том, чтобы при нажатии кнопки (присутствующей в компоненте заголовка) поле формы в другом компоненте обновлялось. Но проблема в том, что значение устанавливается в переменной управления формой, но не отражается в пользовательском интерфейсе. Это пример кода, который я создал. При нажатии кнопки в журнале консоли вы можете увидеть, что форма имеет значение, но не отображается в пользовательском интерфейсе. Ниже я показываю свой код, что я сделал до сих пор :
Дочерний компонент
// In TS
test = this.fb.group({
sample: [""]
});
// In HTML
<form [formGroup]="test">
<input placeholder="Sample" formControlName="sample" />
</form>
Компонент заголовка
// In TS
import { ChildComponent } from "../child/child.component";
constructor(private child: ChildComponent) {}
set() {
this.child.test.patchValue({
sample: "fetched value"
});
console.log(this.child.test.value);
}
// In HTML
<button (click)="set()">ABC</button>
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { ChildComponent } from './child/child.component';
import { AppRouterModule } from './router/router.module';
@NgModule({
imports: [ BrowserModule, FormsModule, AppRouterModule, ReactiveFormsModule ],
declarations: [ AppComponent, HeaderComponent, ChildComponent ],
providers: [ ChildComponent ], // Specified child component to access through different component
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component.html
<app-header></app-header>
<router-outlet></router-outlet>
Итак, это мой код. Кто-нибудь может сказать мне, в чем проблема?
Ответ №1:
Это не то, как взаимодействие компонентов работает в Angular. Чтобы обмениваться данными между компонентами, вы можете использовать либо EventEmitter
для связанных компонентов, либо одноэлементный сервис для несвязанных компонентов.
Вот иллюстрация с использованием одноэлементного сервиса
share.service.ts
import { Injectable } from "@angular/core";
import { ReplaySubject } from "rxjs";
@Injectable()
export class ShareService {
public headerClickSrc = new ReplaySubject<any>(1);
public headerClick$ = this.headerClickSrc.asObservable();
constructor() {}
}
header.component.ts
import { Component } from "@angular/core";
import { ShareService } from "../share.service";
@Component({
selector: "app-header",
templateUrl: "./header.component.html"
})
export class HeaderComponent {
constructor(private share: ShareService) {}
set() {
this.share.headerClickSrc.next("fetched value");
}
}
child.component.ts
export class ChildComponent implements OnInit, OnDestroy {
closed$ = new Subject<any>();
constructor(private fb: FormBuilder, private share: ShareService) {}
test = this.fb.group({
sample: [""]
});
ngOnInit() {
this.share.headerClick$.pipe(
takeUntil(this.closed$)
).subscribe({
next: value => {
this.test.patchValue({
sample: value
});
console.log(this.test.value);
}
});
}
ngOnDestroy() {
this.closed$.next(); // <-- close open subscriptions
}
}
Я изменил ваш Stackblitz
Комментарии:
1. Это выдает ошибку 1. Если
set()
метод запускается один раз изheader.component.ts
ngOnInit
дочернего элемента, он работает нормально. Но после этого, если я перейду к любому другому компоненту и вернусь сюда сноваvalue
subscribe
, значение внутриngOnInit
остается верным. Есть ли способ это исправить?ngOnDestroy
Используется по-прежнему без изменений