组件/由组件创建的服务(观察者模式)

时间:2016-02-23 06:42:33

标签: angular observer-pattern eventemitter

有没有办法创建一个“绑定”的服务?组件或更好的说:一个组件可以创建的服务?

我有以下情况:

我网页上的某个地方是搜索框。页面上的所有组件都应该能够记录此搜索框中的更改,并在更改时收到通知。

我想到实现这一目标的唯一方法就是使用服务。 但是,我不知道如何从我的组件创建服务(在提供服务时我也考虑使用factorysetValue等,但这也不是帮我(?))。

正如您在我的代码中看到的,我添加了一个解决方法,如果多个组件尝试成为"提供商"为了服务。但是,我认为这是一个丑陋的黑客,如果可能的话,我希望以不同的方式做到这一点。

我的搜索组件:

@Component({
    selector: 'my-search-box',
    template: `<input type="text" #box (keyup)="onKey(box.value)" />`,
    providers: [SearchService]
})
export class SearchBoxComponent implements OnInit {

    private _updateSearchFunc : (searchValue: string) => void;

    constructor(private _searchService: SearchService) {
    }

    ngOnInit() {
        this._updateSearchFunc = this._searchService.registerAsProvider();

        // if another component would also try this, it would result in an exception, so it's kind of the "first come first serve" principle..
        //this._updateSearchFunc = this._searchService.registerAsProvider();

        var activeTab = this._cookieManager.get(Constants.CookieNameActiveTab);
        if (activeTab) {
            this._router.navigateByUrl("/" + activeTab);
        }
    }

    onKey(value:string) {
       this._updateSearchFunc(value);
    }
}

我的服务:

export class SearchService {
  private _searchValueChangeEventEmitter: EventEmitter<string> = new EventEmitter();

  private _hasProvider = false;

  constructor() {}

  registerAsProvider() : (searchValue: string) => void {
      if (this._hasProvider) {
          throw new Error("There's already a provider registered!");
      }

      this._hasProvider = true;
      return this.emit;
  }

  subscribe(callback : (searchValue: string) => void) {
    return this._searchValueChangeEventEmitter.subscribe(callback);
  }

  // correct this context
  private emit = (searchValue: string) : void => {
    this._searchValueChangeEventEmitter.emit(searchValue);
  }
}

1 个答案:

答案 0 :(得分:1)

我认为这种方法没有问题,也没有更好的方法。

您必须在bootstrap(AppComponent, [ ..., SearchService])providers: [SeachService] AppComponent中注册该服务,否则整个应用程序无法使用该服务。