【问题标题】:Change component on received event - angular2收到事件时更改组件 - angular2
【发布时间】:2016-06-30 11:06:37
【问题描述】:

我在通知组件发生更改时遇到问题。

假设我有一个组件 A,它发出事件 E(通过某些服务)。组件 B 订阅了该事件。如果我 console.log 收到组件 B 的事件和属性,我确实看到它已更改。

但是,组件的模板保持不变。

我想如果我使用 ChangeDetectorRef 和 changeDetectorRef.detectChanges(),视图会被刷新。 但我不断收到以下错误:

Attempt to use a destroyed view: detectChanges.

这是使用和通知组件的理想方式吗?有更好的吗?

这是我正在使用的代码的简短示例:

这是组件 B,应该更改

import {Component, OnInit, ChangeDetectorRef} from '@angular/core';

import {LiveIndexService} from './services/live-index.service';
import {LiveNavigationService} from '../../services/live-navigation.service';

@Component({
  selector: 'live-index',
  template: require('./index.html'),
  providers: [BetradarService]
})
@CanActivate(() => {
  return areDependenciesFetched();
})
export class LiveIndexComponent implements OnInit {

constructor(
  private _liveNavigationService: LiveNavigationService,
  private _changeDetector: ChangeDetectorRef) {}

public ngOnInit() {
  this._liveNavigationService.sportSelectedEvent$.subscribe(selectedSport => {
  this._selectedSport = selectedSport;
  console.log(this._selectedSport); // I see it is changed, but if I omit next line, it's not working.
  this._changeDetector.detectChanges();
});

} }

这是触发服务并发出事件的组件 A

import {Component, Output, EventEmitter, ChangeDetectorRef} from 'angular2/core';
import {LiveNavigationService} from '../../services/live-navigation.service';

@Component({
   selector: 'live-breadcrumbs',
   template: require('./live-breadcrumbs.html')
})
export class LiveBreadcrumbsComponent {

   private _selectedSport;

   public constructor(private _liveNavigationService: LiveNavigationService,
                 private _changeDetectorRef: ChangeDetectorRef) {}

   // this function is triggered from template (onClick)
   private _selectSport(sport) {
     this._selectedSport = sport;

     this._router.navigate(['Index']); // this will navigate to component B

     this._liveNavigationService.selectSport(sport);
  }
}         

我像这样从服务中发出对象:

import {Injectable, EventEmitter} from '@angular/core';

@Injectable()
export class LiveNavigationService {

   public sportSelectedEvent$: EventEmitter<any> = new EventEmitter<any>();

   public selectSport(sport) {
      this.sportSelectedEvent$.emit(sport);
   }
}

这是html

<div id="breadcrumb">
  <div class="dropdown">
    <div class="wrapper">
        <a class="name">{{ _selectedSport ? _selectedSport.name : 'Sport'}}</a>
        <div class="icon"><span></span></div>
    </div>
    <div class="list">
        <div class="title">Sports</div>
        <div class="list-item" [ngClass]="{selected: sport == _selectedSport}" (click)="_selectSport(sport)" *ngFor="let sport of _sportsWithMatches">{{ sport.name }}</div>
    </div>
</div>

我还在 RC1 上。

【问题讨论】:

  • 你在哪里发出事件?套接字如何参与?我认为问题是由区域未修补的套接字 API 引起的。
  • 我更新了答案,并重命名了标题。起初我想问一下套接字,但我意识到它也发生在 Angular 事件中。
  • 我仍然看不到socket是如何参与的。 selectSport 是从哪里调用的?
  • 这与套接字无关,我更新了标题和正文的问题。

标签: angular


【解决方案1】:

我认为您不应该使用changeDetectorRef。因为change detection strategy 没有设置为 onpush。
我认为如果您将发出逻辑移动到导航完成后,那么您的代码将起作用。 如果你使用的是 rc1 路由器

this._router.navigate(['Index']).then( ()=&gt;this._liveNavigationService.selectSport(sport);)

对于 3.0.0 路由器你可以这样做

this._router.events.subscribe( e => { if(e instance of NavigationEnd && this.router.url == 'index') this._liveNavigationService.selectSport(sport);})

【讨论】:

  • 很遗憾没有,视图没有改变:/
  • 我假设您正在开发模式下运行,并且可能会从 Angular 中得到一个错误。如果是这样,请告诉我。我认为如果您也可以展示您的模板部分会很棒
猜你喜欢
  • 2016-04-13
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 2016-08-08
  • 2017-02-21
  • 2022-11-23
  • 2017-12-10
  • 2021-07-07
相关资源
最近更新 更多