在Angular 5中进行人工广播活动



我正在寻找Angular5中$broadcast$on的类似实现。我发现,我们可以创建自定义服务,使用broadcaster进行此作业。

我有两个平行组件。我想听变更事件。每当父触发事件时,这两个组件应聆听并进行一些处理。但是我正在尝试这种方法,但是,要么只有一个Component1Component2聆听事件。

broadcaster.ts

interface BroadcastEvent {
  key: any;
  data?: any;
}
@Injectable()
export class Broadcaster {
  private _eventBus: Subject<BroadcastEvent>;
  constructor() {
    this._eventBus = new Subject<BroadcastEvent>();
  }
  broadcast(key: any, data?: any) {
    this._eventBus.next({key, data});
  }
  on<T>(key: any): Observable<T> {
    return this._eventBus.asObservable()
      .filter(event => event.key === key)
      .map(event => <T>event.data);
  }
}

component1.ts

@Component({
  selector: 'app-Component1',
  templateUrl: './Component1.component.html',
  styleUrls: ['./Component1.component.css']
})
export class Component1 implements OnInit{
  @Input() data: Student;
  constructor(private broadcaster: Broadcaster) {
  }
  ngOnInit() {

    this.broadcaster.on<string>('selectStudent').subscribe(data => {
      console.log("Component 1");
    });
  }

component2.ts

@Component({
  selector: 'app-Component2',
  templateUrl: './Component2.component.html',
  styleUrls: ['./Component2.component.css']
})
export class Component2 implements OnInit{
  @Input() data: Student;
  constructor(private broadcaster: Broadcaster) {
  }
  ngOnInit() {

    this.broadcaster.on<string>('selectStudent').subscribe(data => {
      console.log("Component 2");
    });
  }

父级

@Component({
  selector: 'app-Component1',
  templateUrl: './Parent .component.html',
  styleUrls: ['./Parent .component.css']
})
export class Parent implements OnInit{
  data: Student;
  constructor(private broadcaster: Broadcaster) {
  }
  ngOnInit() {
  }
  onClick(data) {
   this.data = data;
   this.broadcaster.broadcast('selectStudent');
   console.log("Parent Component");
 }

父html

<app-Component1 [data]="data"> </app-Component1>
<app-Component2 [data]="data"> </app-Component2>

输出

Parent Component
Component 1

输出

Parent Component
Component 2

我缺少什么吗?为什么所有组件都不听的事件?

实际上是一个更好的模式。如果component1component2都是parent组件的孩子,则应在两个孩子中实现ngOnChanges

ngonchanges

当Angular(RE(设置数据结合输入属性时。该方法接收当前和先前属性值的简单对象。 在ngoninit((和一个或多个数据结合的输入属性发生变化之前调用。

component1.ts

@Component({selector: 'comp1', template: `...`})
class Component1 implements OnChanges {
  @Input()
  data: any;
  ngOnChanges(changes: SimpleChanges) {
    const dataChange = changes['data'];
    if (dataChange) {
      // do something with the updated data
    }
  }
}

parent.ts

@Component({
  selector: 'parent', 
  template: `
    <comp1 [data]="data"></comp1>
    <comp2 [data]="data"></comp2>
})
class Component1 implements OnChanges {
  data: any;
  onClick() {
     // if you change the data here it will trigger
     // ngOnChanges in the child components
  }
}

我找到了Angular网站给出的方式。为广播活动写一项服务并收听活动。

datachangedservice.ts

@Injectable()
export class DataChangedService {
    private dataChange = new Subject<Student>();
  dataChanged$ = this.dataChange.asObservable();
  dataChanged(data) {
    this.dataChange.next(data);
  }
}

component1.ts

@Component({
  selector: 'app-Component1',
  templateUrl: './Component1.component.html',
  styleUrls: ['./Component1.component.css']
})
export class Component1 implements OnInit{
  @Input() data: Student;
  constructor(private broadcaster: DataChangedService) {    
  }
  ngOnInit() {
     this.broadcaster.dataChanged$.subscribe( data => {
           // some code
     });        
  }

parent.ts

@Component({
  selector: 'app-Component1',
  templateUrl: './Parent .component.html',
  styleUrls: ['./Parent .component.css']
})
export class Parent implements OnInit{
  data: Student;
  constructor(private broadcaster: DataChangedService) {
  }
  ngOnInit() {
  }
  onClick(data) {
   this.broadcaster.dataChanged(data);
   console.log("Parent Component");
 }

最新更新