何时使用Observable vs EventEmitter vs Dot Rule进行angular2中的变化检测

B H*_*ull 54 angular

我看到有三种方法可以管理Angular2中的变更检测.

  1. 观测

    @Injectable()
    export class TodosService {
        todos$: Observable<Array<Todo>>;
        private _todosObserver: any;
        private _dataStore: {
            todos: Array<Todo>
        };
    
        constructor(private _http: Http) {
            // Create Observable Stream to output our data
            this.todos$ = new Observable(observer => 
                this._todosObserver = observer).share();
    
            this._dataStore = { todos: [] };
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. EventEmitter.

    @Injectable()
    class NameService {
      name: any;
      nameChange: EventEmitter = new EventEmitter();
      constructor() {
        this.name = "Jack";
      }
      change(){
        this.name = "Jane";
        this.nameChange.emit(this.name);
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 点规则

    export interface Info {
       name:string;
    }
    
    @Injectable()
    class NameService {
      info: Info = { name : "Jack" };
      change(){
        this.info.name = "Jane";
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

我的问题是,订阅观看数据变化时,所有三种实现都可以工作.你如何决定何时使用一个而不是另一个,以及每个的缺点是什么.

Thi*_*ier 28

我们试着给你一些提示......

最后一种方法的主要问题是它不适用于原始类型,而只适用于引用.所以我不推荐它......

我认为EventEmitter/ Observable是实现和处理自定义事件的正确方法.它还链接到组件本身(@Ouput),模板(语法[(...)])和async管道中的双向映射.

从文档,EventEmitter用途,Observable但提供了一个适配器,使其按照此处的规定工作:https://github.com/jhusain/observable-spec.在查看EventEmitterAngular2 的类之后,它扩展了Subject类.这不仅仅是一个简单的问题Observable.有关详细信息,请参阅此链接:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md

关于自定义observable的创建,我会说:只有在需要特定的东西时才创建自​​己的observable.否则利用该EventEmitter课程.但是你可以用EventEmitter类和可观察的运算符做很多事情.

总而言之,在这样一个"简单"的用例中,事情并不那么明显,但在更复杂的场景中,EventEmitter/ Observable允许使用运算符定义处理链.经典样本是根据input(在此处this.term定义ngModel的字段)的值更新列表:

this.term.valueChanges
     .debounceTime(400)
     .flatMap(term => this.dataService.getItems(term))
     .subscribe(items => this.items = items);
Run Code Online (Sandbox Code Playgroud)

这篇来自Christoph Burgdorf的精彩博文可以为您提供有关观察者可以处理的内容的一些想法:http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html.

希望它对你有帮助,蒂埃里

  • 作为旁注:根据[EventEmitter的文档](https://angular.io/docs/ts/latest/api/core/index/EventEmitter-class.html),它实际上只应由组件和指令使用; 这意味着它不适用于Observables更受欢迎的服务.我发现[这个](http://stackoverflow.com/questions/36076700/what-is-the-proper-use-of-an-eventemitter)回答相当有用. (15认同)

小智 6

除此之外,我们还需要使用 Event Emitter 来进行子组件和父组件之间的事件绑定。我们最好避免订阅它,好像将来不推荐使用它时,代码将需要再次更改。所以最好避免使用事件发射器,除了子组件和父组件之间的事件绑定。在其他情况下最好使用 Observable。详情请查看此链接... https://www.bennadel.com/blog/3038-eventemitter-is-an-rxjs-observable-stream-in-angular-2-beta-6.htm#comments_47949