Angular2 beta.12 和 RxJs 5 beta.3 的可观察到的错误

Posted

技术标签:

【中文标题】Angular2 beta.12 和 RxJs 5 beta.3 的可观察到的错误【英文标题】:Observable errors with Angular2 beta.12 and RxJs 5 beta.3 【发布时间】:2016-07-16 05:48:29 【问题描述】:

您好,

我正在使用在 VS2015 中运行的 Angular2 beta 12。当我将 rxjs 从 5.0.0-beta.2 更新到 beta.3 时,我遇到了一系列通常与我的承诺有关的异常。

例如

    属性map 不存在于类型Observable<Response> 属性share 不存在于类型Observable<Response> 中 环境模块声明不能指定相对模块名称 环境模块不能嵌套在其他模块或命名空间中。

包.json


  "name": "ASP.NET",
  "version": "0.0.0",
  "scripts": 
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
  ,
  "dependencies": 
    "angular2": "2.0.0-beta.12",
    "systemjs": "0.19.24",
    "es6-promise": "3.1.2",
    "es6-shim": "0.35.0",
    "reflect-metadata": "0.1.3",
    "rxjs": "5.0.0-beta.3", // beta.2 allowed project to build
    "zone.js":"0.6.6"
  ,
  "devDependencies": 
    "gulp": "3.9.1",
    "gulp-concat": "2.6.0",
    "gulp-cssmin": "0.1.7",
    "gulp-uglify": "1.5.3",
    "rimraf": "2.2.8",
    "concurrently": "2.0.0",
    "lite-server": "2.1.0",
    "typescript": "1.8.9"
  

问题与此代码中的地图功能有关:

import Injectable from 'angular2/core';
import Http, Response from 'angular2/http';
import Headers, RequestOptions from 'angular2/http';
import Observable     from 'rxjs/Observable';

import ApplicationVM from '../../Applications/ViewModels/Application.ViewModel';

@Injectable()
export class ApplicationService 
    constructor(private http: Http)  

    private _serviceUrl = './../api/';

    getApplications() 
        return this.http.get(this._serviceUrl + "applications/active")
            .map(res => <ApplicationVM[]>res.json())
           // .map((res: Response) => res.json())
            .do(data => console.log(data)) // eyeball results in the console
            .catch(this.handleError);
    

    private handleError(error: Response) 
        console.log(error);
        return Observable.throw(error.json().error || 'Server error');
    


另一方面,问题在于share()

 constructor(private _http: Http) 
     console.log("constructor");
     this.menulist$ = new Observable(observer => this._menulistObserver = observer).share();
     this.menuState$ = new Observable(observer => this._menuStateObserver = observer).share();
     this.menuWidth$ = new Observable(observer => this._menuWidthObserver = observer).share();

我觉得这可能很重要 - 一系列 rxjs 文件在相对引用 ../../Observable 中带有红色下划线(下面的示例在 interval.d.ts 中)

import  IntervalObservable  from '../../observable/IntervalObservable';
declare module '../../Observable' 
    namespace Observable 
        let interval: typeof IntervalObservable.create;
    

我的 boot.ts

///<reference path="./../node_modules/angular2/typings/browser.d.ts"/>
import bootstrap      from 'angular2/platform/browser';
import ROUTER_PROVIDERS from 'angular2/router';
import AppComponent from './app.component';
import HTTP_PROVIDERS    from 'angular2/http';
import 'rxjs/Rx'; // kitchen sink

// Bootstrap the application and reference the required directives
bootstrap(AppComponent, [ROUTER_PROVIDERS, HTTP_PROVIDERS]);

我的html页面

 <!-- 1. Load libraries -->
    <script src="~/nodelibs/angular2/bundles/angular2-polyfills.js"></script>
    <script src="~/nodelibs/systemjs/system.src.js"></script>
    <script src="~/nodelibs/typescript/lib/typescript.js"></script>
    <script src="~/nodelibs/rxjs/bundles/Rx.js"></script>
    <script src="~/nodelibs/angular2/bundles/angular2.dev.js"></script>

    <script src="~/nodelibs/angular2/bundles/router.dev.js"></script>
    <script src="~/nodelibs/angular2/bundles/http.dev.js"></script>


    <!-- 2. Configure SystemJS -->
    <script>

    var rootPath = "@Url.Content("~/")";

    System.config(
        //transpiler: 'typescript',
        //typescriptOptions:  emitDecoratorMetadata: true ,
        baseURL: rootPath,
        defaultJSExtensions: true,
        packages: 
            app: 
                //format: 'register',
                defaultExtension: 'js'
            , map: 

                'rxjs/observable/*' : 'nodelibs/rxjs/observable/*.js',
                'rxjs/operators/*' : 'nodelibs/rxjs/operators/*.js',
                'rxjs/*' : 'nodelibs/rxjs/*.js'
            
        
    );
    System.import("/app/boot.js")
          .then(null, console.error.bind(console));

    </script>

我很困惑,希望能得到一些帮助。

谢谢,丹。

【问题讨论】:

【参考方案1】:

关于算子,你需要手动导入它们,因为它们默认不包含在 Observable 类中。

为此,您可以执行以下任一操作:

import Observable from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/share';

或(包括所有运算符):

import Observable from 'rxjs/Rx';

否则,通常您不需要在 map 块中的 SystemJS 配置中定义 rxjs。将对应的捆绑文件包含在脚本标签中就足够了。

【讨论】:

我已经包含了“厨房水槽”,即原始问题中提到的 rxjs/Rx。但对于优化 Angular 项目来说,这是一个非常有用的提示。谢谢。 帮我修好了!值得注意的是,据我了解,第一个选项(仅手动导入运算符)是一个性能更高的选项,因为这些导入仅用于 TypeScript 编译。因此,它不会导致将更多代码添加到您的代码库中,就像您使用第二个选项时那样。【参考方案2】:

根据 Angular 的 package.json,您应该完全使用 RxJS 5.0.0-beta.2 https://github.com/angular/angular/blob/master/package.json#L37

【讨论】:

太棒了!我想知道在哪里可以找到我应该使用哪些包的信息。非常感谢。 在我的团队中,我们遇到了完全相同的问题,并且仅适用于 Visual Studio intellisense(webpack TypeScript 编译很好)。虽然我知道当前的 Angular 版本需要 rxjs 5 beta 2,但你知道这两件事有什么关系吗? IE。为什么它构建得很好,但 VS 抱怨?由于ngrx-store,我们需要那个rxjs版本 beta6 现在我相信【参考方案3】:

对于 VS2015,GitHub here 上列出了此问题的解决方法

作为目前的解决方法,您可以将 C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TypeScript\typescriptServices.js 替换为 https://raw.githubusercontent.com/Microsoft/TypeScript/Fix8518/lib/typescriptServices.js 中的文件。不过,请先进行本地备份。

重要提示:确保您使用的是 VS2015 更新 2 并安装了 TypeScript > 1.8.2

(在更新 1 上替换文件后,我的 VS 无法启动)

我正在使用 rxjs 5.0.0-beta。6 顺便说一句。

【讨论】:

是的,你对 Angular RC1 完全正确,这个解决方案可以工作......我最初的问题是针对 Angular beta,应该使用版本 rxjs beta 2。对于带有 Angular RC 的 rxjs beta 6,这与缺少 Typescript 功能有关,这会导致大量构建错误。很高兴看到您的反馈。

以上是关于Angular2 beta.12 和 RxJs 5 beta.3 的可观察到的错误的主要内容,如果未能解决你的问题,请参考以下文章

Rxjs 过滤器运算符不适用于 Angular2 Observable

在 Angular2 中使用 RxJS 链接 observables

angular2 学习笔记 ( rxjs 流 )

Angular2 RxJS 得到“Observable_1.Observable.fromEvent 不是函数”错误

[Angular2 Form] Use RxJS Streams with Angular 2 Forms

缺少可观察的方法 RxJS 5.0.0-beta.0