Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 组件绑定/创建/由组件创建的服务(观察者模式)_Angular_Observer Pattern_Eventemitter - Fatal编程技术网

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

Angular 组件绑定/创建/由组件创建的服务(观察者模式),angular,observer-pattern,eventemitter,Angular,Observer Pattern,Eventemitter,有没有一种方法可以创建一个“绑定”到组件的服务,或者更好地说:一个组件可以创建的服务 我有以下情况: 我的页面上有一个搜索框。页面上的所有组件都应该能够订阅此搜索框中的更改,并在更改时收到通知 实现这一点的唯一方法是使用服务,这在我脑海中浮现。 但是,我不知道如何从我的组件创建服务(我还想过在提供服务时使用工厂或设置值等,但是这对我也没有帮助(?) 正如您在我的代码中看到的,我添加了一个变通方法,如果多个组件试图成为服务的“提供者”,我会抛出一个错误。不过,我认为这是一个丑陋的黑客,并愿意做不同

有没有一种方法可以创建一个“绑定”到组件的服务,或者更好地说:一个组件可以创建的服务

我有以下情况:

我的页面上有一个搜索框。页面上的所有组件都应该能够订阅此搜索框中的更改,并在更改时收到通知

实现这一点的唯一方法是使用服务,这在我脑海中浮现。 但是,我不知道如何从我的组件创建服务(我还想过在提供服务时使用
工厂
设置值
等,但是这对我也没有帮助(?)

正如您在我的代码中看到的,我添加了一个变通方法,如果多个组件试图成为服务的“提供者”,我会抛出一个错误。不过,我认为这是一个丑陋的黑客,并愿意做不同的,如果可能的。 我的搜索组件:

@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);
    }
}
@组件({
选择器:“我的搜索框”,
模板:``,
提供者:[搜索服务]
})
导出类SearchBoxComponent实现OnInit{
private _updatesarchfunc:(searchValue:string)=>void;
构造函数(专用搜索服务:搜索服务){
}
恩戈尼尼特(){
this.\u updatesarchfunc=this.\u searchService.registerAsProvider();
//若另一个组件也尝试这种方法,它将导致一个异常,所以这是一种“先到先得”的原则。。
//this.\u updatesarchfunc=this.\u searchService.registerAsProvider();
var activeTab=this.\u cookieManager.get(Constants.CookieNameActiveTab);
如果(活动选项卡){
这个._router.navigateByUrl(“/”+activeTab);
}
}
onKey(值:字符串){
此._updateSearchFunc(值);
}
}
我的服务:

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);
  }
}
导出类搜索服务{
私有的_searchValueChangeEventEmitter:EventEmitter=新的EventEmitter();
private _hasProvider=false;
构造函数(){}
registerAsProvider():(searchValue:string)=>void{
如果(此提供程序){
抛出新错误(“已注册提供程序!”);
}
这是.\u hasProvider=true;
返回这个.emit;
}
订阅(回调:(searchValue:string)=>void){
返回此。\u searchValueChangeEventEmitter.subscribe(回调);
}
//请更正此上下文
private emit=(searchValue:string):void=>{
此.\u searchValueChangeEventEmitter.emit(searchValue);
}
}

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


您必须在
引导(AppComponent,[…,SearchService])
提供者:[SeachService]中注册服务
AppComponent的
),否则它不能用于整个应用程序。

也许您可以使用具有可观察性的
valueChanges
?嗯,我看不出这有什么帮助。您的示例看起来太复杂了,不适合您尝试做的事情(;如果您制作搜索表单,您可以更轻松地订阅输入控件更改…但是整个应用程序中的所有组件都会收到更改通知吗?您有代码示例吗?“很遗憾”听到它…但无论如何,谢谢。是的,关于注册我知道…)