Angular 2: 如何监视服务变量?

18 浏览
0 Comments

Angular 2: 如何监视服务变量?

我正在尝试在Angular中实现类似委托模式的功能。

当用户点击一个nav-item时,我想调用一个函数,该函数会触发一个事件,并由其他监听该事件的组件处理。

这是场景:我有一个Navigation组件:

import {Component, Output, EventEmitter} from 'angular2/core';

@Component({

// 其他属性为了简洁起见省略

events : ['navchange'],

template:`

`

})

export class Navigation {

@Output() navchange: EventEmitter = new EventEmitter();

selectedNavItem(item: number) {

console.log('selected nav item ' + item);

this.navchange.emit(item)

}

}

这是观察组件:

export class ObservingComponent {

// 我如何观察这个事件?

// <----------观察/注册事件?-------->

public selectedNavItem(item: number) {

console.log('item index changed!');

}

}

关键问题是,我如何使观察组件观察到所讨论的事件?

0
0 Comments

Angular 2:如何监视服务变量?

问题的出现原因:

在Angular 2中,如果一个组件想要监视一个服务的变量,那么在服务中对变量的更新并不会自动触发组件的更新。这导致了一个问题,即如何在服务变量发生变化时通知组件进行更新。

解决方法:

有两种常见的解决方法:

1. 使用BehaviorSubject:

BehaviorSubject是一种特殊类型的Subject,Subject是一种特殊类型的Observable,可以作为Observable和Observer。可以像其他Observable一样订阅消息,并在订阅时返回源Observable发出的主题的最后一个值。

优点:不需要像父子组件之间传递数据那样的关系。

在NavService服务中使用BehaviorSubject来实现这个功能:

import {Injectable} from '/core'
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
@Injectable()
export class NavService {
  private navSubject$ = new BehaviorSubject(0);
  
  constructor() {  }
  
  // 当新项目被点击时触发事件
  navItemClicked(navItem: number) {
    this.navSubject$.next(number);
  }
  
  // 允许Observer组件仅订阅发出的数据
  getNavItemClicked$() {
    return this.navSubject$.asObservable();
  }
}

在Navigation组件中使用NavService来触发事件:

@Component({
  selector: 'navbar-list',
  template:`
    
})
export class Navigation {
  constructor(private navService:NavService) {}
  
  navItemClicked(item: number) {
    this.navService.navItemClicked(item);
  }
}

在ObservingComponent组件中订阅NavService的变化并更新:

@Component({
  selector: 'obs-comp',
  template: `obs component, item: {{item}}`
})
export class ObservingComponent {
  item: number;
  itemClickedSubcription:any
  
  constructor(private navService:NavService) {}
  
  ngOnInit() {
    this.itemClickedSubcription = this.navService
                                      .getNavItemClicked$
                                      .subscribe(
                                        item => this.selectedNavItem(item)
                                       );
  }
  
  selectedNavItem(item: number) {
    this.item = item;
  }
  
  ngOnDestroy() {
    this.itemClickedSubcription.unsubscribe();
  }
}

2. 使用@Input和@Output装饰器:

另一种常见的方法是使用@Input和@Output装饰器,父组件将数据传递给子组件,子组件通过触发事件来通知父组件。

例如,Sharma提供的答案中给出了这种方法的示例代码。

0
0 Comments

问题的出现的原因是:在Angular 2中,当一个服务的变量发生变化时,如何实时监测这个变化。解决方法是使用EventEmitter或Observable来实现。

原文中给出了两种解决方法。第一种方法是将EventEmitter放入一个服务中,然后在需要监测变化的组件中直接订阅和取消订阅这个事件。但是这种方法有一些问题,比如需要在组件销毁时手动取消订阅,并且需要将组件作为参数传递给订阅方法,以便在回调时正确设置this。

第二种方法是直接让需要监测变化的组件订阅服务中的EventEmitter属性。这样就不需要手动取消订阅了,但是仍然需要将组件作为参数传递给订阅方法。

为了让服务更加封装,可以在服务中添加一个getNavChangeEmitter()方法,然后在组件中使用这个方法来订阅事件。

作者对这两种方法都不太满意,因为第一种方法需要手动取消订阅,第二种方法需要将组件作为参数传递给订阅方法。作者希望能有更加简洁的解决方法。对于第二种方法中的问题,作者提出了一个修复方法,即将回调函数传递给订阅方法时,直接使用箭头函数来避免出现this的问题。

问题的出现原因是如何实时监测服务变量的变化,解决方法是使用EventEmitter或Observable,并给出了两种具体的实现方法。

0
0 Comments

Angular 2: 如何监听服务变量?

在这个问题中,我们需要解决一个问题:如何在Angular 2中监听服务变量的变化?下面是一些解决方法:

1. 使用BehaviorSubject:

BehaviorSubject是Subject的一种变体,它有“当前值”的概念。我们可以利用这一点,每当我们创建一个ObservingComponent时,它会自动从BehaviorSubject获取当前的导航项值。

2. 使用ReplaySubject:

ReplaySubject是Subject的另一种变体。如果你想要等到一个值真正产生,可以使用ReplaySubject(1)。ReplaySubject始终提供最新的值,但不需要一个必需的初始值,因此服务可以在返回第一个值之前进行一些异步操作。对于只想要一个值的情况,可以在订阅上使用first()。如果使用first(),则不需要取消订阅。

下面是一个使用BehaviorSubject的示例代码:

import {Injectable} from '/core'
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
@Injectable()
export class NavService {
  private _navItemSource = new BehaviorSubject(0);
  navItem$ = this._navItemSource.asObservable();
  changeNav(number: number) {
    this._navItemSource.next(number);
  }
}

下面是一个使用NavService的ObservingComponent示例代码:

import {Component} from '/core';
import {NavService} from './nav.service';
import {Subscription} from 'rxjs/Subscription';
@Component({
  selector: 'obs-comp',
  template: `obs component, item: {{item}}`
})
export class ObservingComponent {
  item: number;
  subscription: Subscription;
  constructor(private _navService: NavService) {}
  ngOnInit() {
    this.subscription = this._navService.navItem$
       .subscribe(item => this.item = item)
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

下面是一个使用NavService的Navigation组件示例代码:

@Component({
  selector: 'my-nav',
  template:`
    
    `
})
export class Navigation {
  item = 1;
  constructor(private _navService: NavService) {}
  selectedNavItem(item: number) {
    console.log('selected nav item ' + item);
    this._navService.changeNav(item);
  }
}

以上是解决问题的方法和示例代码。通过使用BehaviorSubject或ReplaySubject,我们可以监听服务变量的变化并作出相应的处理。这些方法可以帮助我们更好地管理和处理Angular 2中的服务变量。

0