【问题标题】:How to load RxJS in a minimal Angular 2 app using systemjs?如何使用 systemjs 在最小的 Angular 2 应用程序中加载 RxJS?
【发布时间】:2023-03-05 00:55:01
【问题描述】:

我无法使用 RxJS 获得最小的 Angular 2 应用程序。我正在使用 Typescript (tsc 1.6.2) 和 systemjs 进行模块加载。如何让 systemjs 正确加载 Rx 模块?我已经没有什么想法可以尝试了,如果我能指出我做错了什么,我将不胜感激。模块加载对我来说有点神奇。非常沮丧。

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
    <script src="../node_modules/es6-shim/es6-shim.js"></script>
    <script src="../node_modules/systemjs/dist/system.src.js"></script>
    <script src="../node_modules/rx/dist/rx.lite.js"></script>
    <script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
</head>

<body>
    <app>App loading...</app>
    <script>
        System.config({
            packages: { 'app': { defaultExtension: 'js' } }
        });
        System.import('app/app');
    </script>
</body>
</html>

app.ts

/// <reference path="../../node_modules/rx/ts/rx.all.d.ts" />
import { bootstrap, Component, View } from 'angular2/angular2';
import * as Rx from 'rx';

@Component({
    selector: 'app'
})
@View({
        template: `Rx Test`
})
export class App {
    subject: Rx.Subject<any> = new Rx.Subject<any>();
}
bootstrap(App);

SystemJS 尝试加载一个不存在的文件:

只要我在上面的代码中注释掉 subject,一切都会运行良好,因为不会尝试加载不存在的文件(并且不会加载 rx)。 p>

【问题讨论】:

    标签: javascript angular typescript rxjs


    【解决方案1】:

    更新 angular2 beta 0

    Angular2 不再将 RxJS 捆绑在 Angular2 本身中。现在您必须单独导入运算符。这是我answered here 的重要突破性变化。因此,请参考该答案,因为该答案已过时且不再适用。

    2015 年 12 月 11 日更新

    Alpha46 正在使用 RxJS alpha 0.0.7(即将成为 0.0.8)。由于这个 ng2 alpha 版本您不再需要下面的解决方案,您现在可以直接从 angular2/angular 导入 ObservableSubject 等,因此可以丢弃原始答案

    import {Observable, Subject} from 'angular2/angular2';
    

    ======================================

    Angular2 不再使用旧的RxJS,他们移到了新的RxJS 5(又名 RxJS Next),所以它会与 Http 和 EventEmitter 发生冲突。

    所以首先删除 rx.lite.js 的导入和脚本。

    相反,您必须这样做(您的配置中不需要脚本或映射)

    编辑

    这一行是为了让它在 plnkr 中工作,但在我的项目中我只需要添加一些其他的东西

    Plnkr 版本

    import Subject from '@reactivex/rxjs/dist/cjs/Subject';
    

    离线版

    import * as Subject from '@reactivex/rxjs/dist/cjs/Subject';
    

    离线版注意事项

    如果您在本地项目中尝试第一种 plnkr 方法,您可能会收到此消息错误

    TypeError: Subject_1.default is not a function
    

    因此,对于您的本地(离线)版本,您应该使用第二种方法(使用星号)。

    注意

    Subject 中没有括号,this conversation 中对此进行了解释(我遇到了同样的问题,哈哈)

    这是plnkr not failing

    我希望它有所帮助。如果我错过了什么,请告诉我;)

    【讨论】:

    • 埃里克,感谢您抽出宝贵时间回复!这为我解决了部分谜团。很抱歉花了这么长时间才回复你,我今天大部分时间都在试图让同一个项目离线工作(我必须说没有任何真正的成功)。我正在使用 VSC 和 Typescript 1.6.2,与您的示例中使用的转译器相同。在“在线”版本中从 app.ts 生成的代码有一个稍微不同的标头,这似乎产生了很大的不同(它调用System.register(...))。你有没有成功地用 VSC/tsc 在本地编译和运行它?
    • 您是否遇到任何错误?事实上,在我的离线版本(我自己的项目)中,我有import * as Subject from '...'(与我的答案有点不同。你还有别的吗?你的在线版本和离线版本有多大不同?
    • 所以您在运行时遇到错误?还是默默地失败了?您是否在使用诸如 JSPM、Webpack 之类的工具?你可以创建一个 repo 以便我可以克隆它并查看它吗?
    • 没有错误,转译没问题,智能感知工作(为此,我在 npm_modules 中添加了@reactivex alpha 4,与角度使用相同)。它在运行时 (TypeError: Subject_1.default is not a function) 失败,因为它似乎没有加载 rx 模块/类型。我将 config.js 更改为加载“app.js”和默认分机“js”,并删除了 index.html 中对 typescript.js 的引用。这让我发疯了。
    • 好吧,这很有趣。编译器会抱怨,但生成的输出与在线版本中生成的输出相同 - 并且它在运行时工作。因此,除了 tsc 输出 (src/app.ts(11,14): error TS2304: Cannot find name 'Subject'. src/app.ts(11,29): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.) 之外一切正常。非常感谢你的帮助。下一杯啤酒在我身上:)。
    【解决方案2】:

    对于 angular2 alpha52 使用 rxjs 5alpha.14

    <script>
    System.config({
      map: { rxjs: 'node_modules/rxjs' },
      packages: {
        rxjs: { defaultExtension: 'js' },
        'app': {defaultExtension: 'js'}
      }
    });
    System.import('app/app');
    </script>
    

    但您必须像此示例一样单独导入每个运算符

    import { Subject } from 'rxjs/Subject';
    import { Observable } from 'rxjs/Observable';
    
    require('rxjs/add/operator/map');
    require('rxjs/add/operator/scan');
    require('rxjs/add/operator/mergemap');  //for flatmap
    require('rxjs/add/operator/share');
    require('rxjs/add/operator/combinelatest-static'); //for combinelatest
    

    【讨论】:

      【解决方案3】:

      在 Angular 4 发布后发布此答案。尝试从 Rxjs 加载最低限度,因为即使使用 AOT 的 Angular prod build 也会达到 300kb

      希望对你有帮助。

      import { Injectable } from '@angular/core';
      import {Http} from "@angular/http";
      import {Observable} from "rxjs/Observable";
      import 'rxjs/add/operator/map';// load this in main.ts
      
      import {AllUserData} from "../../../shared/to/all-user-data";
      
      @Injectable()
      export class ThreadsService {
      
        constructor(private _http: Http) { }
      
        loadAllUserData(): Observable<AllUserData> {
          return this._http.get('/api/threads')
            .map(res => res.json());
        }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2018-05-18
        • 2017-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-17
        • 2016-06-09
        • 1970-01-01
        相关资源
        最近更新 更多