Angular 7 - 重新加载/刷新数据不同的组件

Posted

技术标签:

【中文标题】Angular 7 - 重新加载/刷新数据不同的组件【英文标题】:Angular 7 - Reload / refresh data different components 【发布时间】:2019-07-12 13:42:24 【问题描述】:

组件2发生变化时如何刷新不同组件1的数据。这两个组件不在同一个父节点下。

customer.service.ts

export class UserManagementService extends RestService 

  private BASE_URL_UM: string = '/portal/admin';

  private headers = new HttpHeaders(
    'Authorization': localStorage.getItem('token'),
    'Content-Type': 'application/json'
  );

  constructor(protected injector: Injector,
    protected httpClient: HttpClient) 
    super(injector);
  
  getEapGroupList(): Observable < EapGroupInterface > 
    return this.get < GroupInterface >
      (this.getFullUrl(`$this.BASE_URL_UM/groups`), 
        headers: this.headers
      );
  

  updateGroup(body: CreateGroupPayload): Observable < CreateGroupPayload > 
    return this.put < GroupPayload >
      (this.getFullUrl(`$this.BASE_URL_UM/group`), body, 
        headers: this.headers
      );
  

Component1.ts

export class UserGroupComponent implements OnInit 

  constructor(private userManagementService: UserManagementService) 

  ngOnInit() 
    this.loadGroup();
  

  loadGroup() 
    this.userManagementService.getEapGroupList()
      .subscribe(response => 
        this.groups = response;
      )
  

<mat-list-item *ngFor="let group of groups?.groupList" role="listitem">
  <div matLine [routerLink]="['/portal/user-management/group', group.groupCode, 'overview']" [routerLinkActive]="['is-active']">
    group.groupName
  </div>
</mat-list-item>
<mat-sidenav-content>
  <router-outlet></router-outlet>
</mat-sidenav-content>

component2.ts

setPayload() 
  const formValue = this.newGroupForm.value
  return 
    'id': '5c47b24918a17c0001aa7df4',
    'groupName': formValue.groupName,
  


onUpdateGroup() 
    this.userManagementService.updateGroup(this.setPayload())
      .subscribe(() => 
          console.log('success);
          )
      

当我在 component1 中更新 onUpdateGroup() api 时,loadGroup() 应该在 component2

中刷新

【问题讨论】:

【参考方案1】:

创建一个包含主题的@Injectable 服务类。让两个组件查看此服务类主题,以了解何时执行。一个类可以在主题上调用 .next() ,另一个可以订阅它并在获得更新时调用它自己的函数。

【讨论】:

【参考方案2】:

将检索数据的代码移至服务,以便服务维护groups

然后将组件 1 中的数据包装在 getter 中:

get groups() 
  return this.userManagementService.groups

那么每次数据发生变化,Angular的依赖注入都会自动调用getter,获取最新的值。

修改后的服务

export class UserManagementService extends RestService 
  groups;
  private BASE_URL_UM: string = '/portal/admin';

  private headers = new HttpHeaders(
    'Authorization': localStorage.getItem('token'),
    'Content-Type': 'application/json'
  );

  constructor(protected injector: Injector,
    protected httpClient: HttpClient) 
    super(injector);

    // Get the data here in the service
    this.loadGroup();
  

  getEapGroupList(): Observable < EapGroupInterface > 
    return this.get < GroupInterface >
      (this.getFullUrl(`$this.BASE_URL_UM/groups`), 
        headers: this.headers
      );
  

  loadGroup() 
    this.getEapGroupList()
      .subscribe(response => 
        this.groups = response;
      )
  

  updateGroup(body: CreateGroupPayload): Observable < CreateGroupPayload > 
    return this.put < GroupPayload >
      (this.getFullUrl(`$this.BASE_URL_UM/group`), body, 
        headers: this.headers
      ).pipe(
         // Reget the data after the update
         tap(() => this.loadGroup()
      );
  

修订的组件 1

export class UserGroupComponent implements OnInit 
    get groups() 
      return this.userManagementService.groups
    

  constructor(private userManagementService: UserManagementService) 

  ngOnInit() 

  

注意:此代码未经语法检查!

我在这里有一个类似的工作示例:https://github.com/DeborahK/Angular-Communication/tree/master/APM-FinalWithGetters

(查看 product-shell 文件夹文件以及 product.service.ts)

【讨论】:

【参考方案3】:

网上有很多例子,你可以使用“Subject”和Output EventEmitter。两者都会起作用。下面的例子是共享服务的示例代码。尝试使用它。

@Injectable()
export class TodosService 
  private _toggle = new Subject();
  toggle$ = this._toggle.asObservable();

  toggle(todo) 
    this._toggle.next(todo);
  


export class TodoComponent 
  constructor(private todosService: TodosService) 

  toggle(todo) 
    this.todosService.toggle(todo);
  


export class TodosPageComponent 
  constructor(private todosService: TodosService) 
    todosService.toggle$.subscribe(..);
  

【讨论】:

【参考方案4】:
Write a common service and call the same in both components.
like below:

common service: 
           dataReferesh = new Subject<string>();
           refereshUploadFileList()
            this.dataReferesh.next();
            

component2.ts:

    setPayload() 
      const formValue = this.newGroupForm.value
      return 
        'id': '5c47b24918a17c0001aa7df4',
        'groupName': formValue.groupName,
      
    

        onUpdateGroup() 
         this.userManagementService.updateGroup(this.setPayload())
           .subscribe(() => 
             this.shareservice.refereshUploadFileList(); 
               )
           

And component1.ts:


         ngOnInit() 
         this.loadGroup();
         this.shareservice.dataReferesh.subscribe(selectedIndex=> this.loadGroup());
          

【讨论】:

以上是关于Angular 7 - 重新加载/刷新数据不同的组件的主要内容,如果未能解决你的问题,请参考以下文章

如何以权利方式刷新 Angular 7 页面?

Angular 2.0 路由器无法重新加载浏览器

Angular 5 - 如何在初始化后重新加载组件

nginx - django 2 -angular 6 / 角度路由在重新加载页面后得到 404

Angular不需要的重新加载页面

烧瓶自动重新加载不刷新浏览器