Angular 2异步管道不会自动呈现/更新Observable数据

前端之家收集整理的这篇文章主要介绍了Angular 2异步管道不会自动呈现/更新Observable数据前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我面临着Angular2路由器和异步管道的问题.

我试图渲染一个RxJs Observable,数据不会自动渲染.

必须单击链接获取要呈现的数据的路径.

这是根应用程序:

import {bootstrap}    from 'angular2/platform/browser';
import {HTTP_PROVIDERS} from 'angular2/http';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {AppComponent} from './app.component.ts';

bootstrap(AppComponent,[HTTP_PROVIDERS,ROUTER_PROVIDERS]);

这是根组件:

import {Component} from 'angular2/core';
import {RouteConfig,ROUTER_DIRECTIVES} from 'angular2/router';
import {FirstComponent} from './app.first-component.ts';
import {SecondComponent} from './app.second-component.ts';
import {AppService} from "./app.services.ts";


@Component({
    selector: 'my-app',providers: [AppService,FirstComponent,SecondComponent],directives: [FirstComponent,SecondComponent,ROUTER_DIRECTIVES],template: `<h1>An Angular 2 App</h1>
               <a [routerLink]="['First']">first-default</a> 
               <a [routerLink]="['Second']">second</a> 
               <router-outlet></router-outlet>`
})
@RouteConfig([
    {path: '/',name: 'First',component: FirstComponent,useAsDefault: true},{path: '/second',name: 'Second',component: SecondComponent}
])
export class AppComponent {
}

这是第一个组成部分:

import {Component} from "angular2/core";
import {AppService} from "./app.services.ts";
import "rxjs/Rx";


@Component({
    selector: 'my-first',template: `
<div>
    <ul>
        <li *ngFor="#s of appService.someObservable$| async">
           a string: {{ s }}
        </li>
    </ul>
 </div>`
})
export class FirstComponent {

    constructor(private appService:AppService) {
        console.log('constructor','first');
    }
}

最后是服务(数据所在的位置):

import {Injectable} from "angular2/core";
import {Observable} from "rxjs/Rx";

@Injectable()
export class AppService {

    constructor() {
        console.log('constructor','appService');
        this.constructSomeObservable();
    }

    someObservable$:Observable <string[]>;

    constructSomeObservable() {
        this.someObservable$= Observable.create(observer => {
                const eventSource = new EventSource('/interval-sse-observable');
                eventSource.onmessage = x => observer.next(JSON.parse(x.data));
                eventSource.onerror = x => observer.error(console.log('EventSource Failed'));
                return () => {
                    eventSource.close();
                };
            })
            .startWith([])
            .scan((acc,value) => acc.concat(value));
    }
}

我在路由器或管道上出了什么问题?

请参阅github here上的示例项目.

编辑:这是组件的修改版本:

import {Component} from "angular2/core";
import {AppService} from "./app.services.ts";
import {Observable} from "rxjs/Rx";


@Component({
    selector: 'my-first',template: `
<div>
    <ul>
        <li *ngFor="#s of someObservable$| async">
           a string: {{ s }}
        </li>
    </ul>
 </div>`
})
export class FirstComponent {

    someObservable$:Observable <string[]>;

    constructor(private appService:AppService) {
        console.log('constructor','first');
        this.someObservable$= appService.someObservable$;
    }
}

数据未在模板中更新.它与两个/单向绑定有关吗?

我认为angular zone不会修复eventSource.onmessage发出的事件,例如setTimeout,SetInterval或xhr请求

来自angular2-polyfills.js

/***/ function(module,exports,__webpack_require__) {

    /* WEBPACK VAR INJECTION */(function(global) {"use strict";
    __webpack_require__(1);
    var event_target_1 = __webpack_require__(2);
    var define_property_1 = __webpack_require__(4);
    var register_element_1 = __webpack_require__(5);
    var property_descriptor_1 = __webpack_require__(6);
    var utils_1 = __webpack_require__(3);
    var set = 'set';
    var clear = 'clear';
    var blockingMethods = ['alert','prompt','confirm'];
    var _global = typeof window == 'undefined' ? global : window;
    patchTimer(_global,set,clear,'Timeout');
    patchTimer(_global,'Interval');
    patchTimer(_global,'Immediate');
    patchTimer(_global,'request','cancelMacroTask','AnimationFrame');
    patchTimer(_global,'mozRequest','mozCancel','webkitRequest','webkitCancel','AnimationFrame');
    for (var i = 0; i < blockingMethods.length; i++) {
        var name = blockingMethods[i];
        utils_1.patchMethod(_global,name,function (delegate,symbol,name) {
            return function (s,args) {
                return Zone.current.run(delegate,_global,args,name);
            };
        });
    }
    event_target_1.eventTargetPatch(_global);
    property_descriptor_1.propertyDescriptorPatch(_global);
    utils_1.patchClass('MutationObserver');
    utils_1.patchClass('WebKitMutationObserver');
    utils_1.patchClass('FileReader');
    define_property_1.propertyPatch();
    register_element_1.registerElementPatch(_global);
    // Treat XMLHTTPRequest as a macrotask.
    patchXHR(_global);
    var XHR_TASK = utils_1.zoneSymbol('xhrTask');
    function patchXHR(window) {
        function findPendingTask(target) {
            var pendingTask = target[XHR_TASK];
            return pendingTask;
        }

因此,您需要为eventsource.onmessage包装回调类似于:

app.services.ts

import {Injectable,NgZone} from "angular2/core"; // <=== 1) Don't forget to import the NgZone class
import {Observable} from "rxjs/Rx";

@Injectable()
export class AppService {

  constructor(private zone: NgZone) { // <== 2) Don't forget also to inject zone in constructor
    console.log('constructor','appService');
    this.constructSomeObservable();
  }

  someObservable$: Observable<string[]>;

  constructSomeObservable() {
    this.someObservable$= Observable.create(observer => {
      const eventSource = new EventSource('/interval-sse-observable');
      eventSource.onmessage = x => this.zone.run(() => observer.next(JSON.parse(x.data))); // <=== 3) Wrap onmessage event
      eventSource.onerror = x => observer.error(console.log('EventSource Failed'));
      return () => {
        eventSource.close();
      };
    })
      .startWith([])
      .scan((acc,value) => acc.concat(value));
  }
}

猜你在找的Angularjs相关文章