Angular中如何调用通过router-outlet挂载的兄弟组件的方法?
问题答复
首先明确你的疑问:不能手动实例化ItemList组件调用方法。Angular框架会负责管理页面上渲染的所有组件实例,你自行创建的组件实例和页面中实际运行的实例没有关联,调用方法不会对页面展示产生任何影响。
针对你的需求,最简洁的实现方案是借助已经全局注入的ItemService作为通信中间件,通过RxJS的Subject实现数据变更事件广播,具体修改步骤如下:
步骤1:修改ItemService,新增变更通知逻辑
首先导入RxJS的Subject,新增事件通知相关逻辑,同时在新增条目请求成功后发送通知:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { ActivatedRoute, Router } from '@angular/router'; import { Observable, Subject } from 'rxjs'; import { Item } from './item.model'; // 替换为你实际的Item类型导入路径 @Injectable() export class ItemService { // 新增:私有Subject用于发送事件,对外只暴露只读的Observable防止外部随意发送事件 private itemChanged = new Subject<void>(); itemChanged$ = this.itemChanged.asObservable(); constructor(private http: HttpClient, private route: ActivatedRoute, private router: Router) { } fetchItems(): Observable<Item[]> { return this.http.get<Item[]>('https://localhost:44321/api/TodoItems'); } fetchItem(id: number): Observable<Item> { return this.http.get<Item>('https://localhost:44321/api/TodoItems' + '/' + id); } createAndStorePost(description: string, isComplete: boolean) { var item = { description: description, isComplete: isComplete }; this.http.post('https://localhost:44321/api/TodoItems', item) .subscribe(Response => { // 新增:请求成功后发送数据变更通知 this.itemChanged.next(); }); } deleteItem(id: number): Observable<Item> { return this.http.delete<Item>('https://localhost:44321/api/TodoItems' + '/' + id); } updateItem(id:number, item: Item) { this.http.put<Item>('https://localhost:44321/api/TodoItems' + '/' + id, item).subscribe(() => { // 后续如果需要修改后自动刷新,这里也可以加发送通知的逻辑 this.itemChanged.next(); }); } }
步骤2:修改ItemListComponent,订阅变更通知
订阅服务中的变更事件,收到通知后自动触发列表拉取逻辑,同时添加组件销毁时的订阅清理逻辑避免内存泄漏:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { Subscription } from 'rxjs'; import { Item } from './item.model'; // 替换为你实际的Item类型导入路径 import { ItemService } from './item.service'; @Component({ selector: 'app-item-list', templateUrl: './item-list.component.html', styleUrls: ['./item-list.component.css'] }) export class ItemListComponent implements OnInit, OnDestroy { items: Item[] = []; // 用于存储订阅,后续销毁时取消 private changeSub?: Subscription; constructor(private route: ActivatedRoute, private router: Router, private itemService: ItemService) { } ngOnInit(): void { this.onFetchItems(); // 订阅数据变更事件,收到事件就刷新列表 this.changeSub = this.itemService.itemChanged$.subscribe(() => { this.onFetchItems(); }) } ngOnDestroy(): void { // 组件销毁时取消订阅,避免内存泄漏 this.changeSub?.unsubscribe(); } onFetchItems() { this.itemService.fetchItems().subscribe(Response => { this.items = Response; }); } onNewItem() { this.router.navigate(['new'], {relativeTo: this.route}); } }
以上修改完成后,每次新增条目请求成功后,列表会自动刷新,不需要手动点击按钮。如果后续需要实现删除、修改后自动刷新,只需要在对应服务方法的请求成功回调中调用this.itemChanged.next()即可。
内容的提问来源于stack exchange,提问作者user13129304
相关产品推荐
相关产品推荐

