在RC.5中,.subcribe()中没有触发ChangeDetection?

时间:2016-08-10 01:04:14

标签: angular

我有一个当前在RC.4中运行的应用程序,我正在升级到RC.5。我已经停止使用旧的Forms指令,并且我已经更新以使用NgModule来启动应用程序。

但是由于我的应用程序通过ajax调用加载了大部分信息,我立即遇到了问题。我订阅了这些Observable并将数据放在组件中,就像我在RC.4中一样。通常的行看起来像这样:

api.GoGetData().subscribe((data) => this.myData = data);

在RC.4中,这没有任何问题。现在我已经开始运行RC.5,我发现View没有更新以显示此绑定数据。在Chrome的开发工具中,我发现正在发出请求,如果我将上述行更新为:

api.GoGetData().subscribe((data) => {
  this.myData = data;
  debugger;
});

然后我点击了断点,我可以正确地看到数据。

似乎我必须手动拨打一个勾号:

constructor(api: Api, appref: ApplicationRef) {
  ...
  this.api.GoGetData().subscribe((data) => {
    this.myData = data;
    appref.tick();
  });
  ...
}

如果我这样做,则强制更改检测,并且我的UI会相应更新。这可能有用,但它可能不是Angular2的方法。

在Angular2 RC.5中,当我从Http请求的Observable的订阅回调中更改组件变量时,我需要做什么才能触发变量检测?

编辑:我已删除了很多现有代码,因此我可以尝试将其整理出来。这就是我现在所拥有的:

的index.html

<html>
  <body>
    <app>Loading</app>
    <script src="app/lib/es6-shim.min.js"></script>
    <script src="app/lib/zone.min.js"></script>
    <script src="app/lib/Reflect.js"></script>
    <script src="app/lib/system-polyfills.js"></script>
    <script src="app/lib/system.js"></script>
    <script src="app/systemjs.config.js"></script>
    <script>
      System.import('app/boot').catch(function(err){ console.error(err); });
    </script>
  </body>
</html>

boot.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';

import { TestComponent } from './components/test';
import { TestApi } from './components/testapi';

@NgModule({
  imports: [ BrowserModule, HttpModule ],
  declarations: [ TestComponent ],
  providers: [ TestApi ],
  bootstrap: [ TestComponent ]
})
export class AppModule { }

platformBrowserDynamic().bootstrapModule(AppModule);

test.ts

import { Component } from '@angular/core';
import { TestApi } from './testapi';

@Component({
  selector: 'app',
  template: 'TEST<br/><br/>{{ myData }}'
})
export class TestComponent { 
  myData: any;
  constructor(private api: TestApi) {
    this.api.GoGetData().subscribe(data => {
      this.myData = data;
      console.log(this.myData);
    });
  }
}

testapi.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class TestApi {
  constructor(private http: Http) { }

  GoGetData() {
    return this.http.get('test.txt').map(res => res.text());
  }
}

systemjs.config.js

(function(global) {

  var ngVer = '@2.0.0-rc.5'; // lock in the angular package version; do not let it float to current!
  // var routerVer = '@3.0.0-rc.1'; // lock router version
  var formsVer = '@0.3.0'; // lock forms version

  //map tells the System loader where to look for things
  var  map = {
    'app':                        'app',

    '@angular':                   'https://npmcdn.com/@angular', // sufficient if we didn't pin the version
    'rxjs':                       'https://npmcdn.com/rxjs@5.0.0-beta.6'
 };

  //packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' }
  };

  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'http',
    'forms',
    'platform-browser',
    'platform-browser-dynamic',
  ];

  // Add map entries for each angular package
  // only because we're pinning the version with `ngVer`.
  ngPackageNames.forEach(function(pkgName) {
    var url = pkgName;
    switch (pkgName) {
      case 'forms':
        url += formsVer;
        break;
      default:
        url += ngVer;
        break;
    }
    map['@angular/'+pkgName] = 'https://npmcdn.com/@angular/' + url;
  });

  // Add package entries for angular packages
  ngPackageNames.forEach(function(pkgName) {

    // Bundled (~40 requests):
    packages['@angular/'+pkgName] = { main: 'bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
  });

  var config = {
    map: map,
    packages: packages
  };

  System.config(config);

})(this);

这让我疯狂了!我有一个test.txt包含&#34;来自服务器的Hello!&#34;它在控制台中显得很好,但我只在页面上看到TEST。没有错误,警告,任何事情。评论中yurzui的plnkr对我有用,但不适用于我自己的代码。

1 个答案:

答案 0 :(得分:0)

对于我的情况,事实证明systemjs-polyfills.js中的某些东西是根本原因。简单地说不包括它足以解决我的问题。