【问题标题】:Cannot read property 'injector' of null when downgrading angular 2 service降级 Angular 2 服务时无法读取 null 的属性“注入器”
【发布时间】:2017-11-16 09:14:24
【问题描述】:

每个人。我需要帮助解决此类问题。

我的 angular 1.x app.js 有这样的代码:

angular.module('app', []);

angular.module('app.test', ['app'])
    .config(($stateProvider) => 
        $stateProvider.state('base', {
                url: '/',
                controller: 'TestStateCtrl',
                resolve: {
                    authenticationCheck: ['angularNg1Service', angularNg1Service=> {
                        angularNg1Service.test1();
                    }]
                }
            })
        })
    .run((angularNg1Service) => {
        angularNg1Service.test2();

    });

这是我的 angularNg1Service 的代码:

    angular.module('app')
    .service('angularNg1Service',
        function (angularNg2Service} {
            //some code here 
}

我的 angularNg2Service 在 angular 1.x 模块的.run 功能启动之前被降级:

window['angular']
        .module('app')
        .factory(
            'angularNg2Service',
            upgradeAdapter.downgradeNg2Provider(AngularNg2Service)
        );

但是,我有一条错误消息:

无法读取 null 的属性“注入器”

Angular 1.x 模块的.run 函数启动时。

这是我的 main.ts 文件:

import { upgradeAdapter } from './upgradeAdapter';
import { bootstrapNg1Components } from './app/ng1Components';    
bootstrapNg1Components(upgradeAdapter);// this function downgarades my AngularNg2Service

upgradeAdapter.bootstrap(document.querySelector('html'), ['app.start']);

我已经阅读了一些类似的问题,但没有找到任何解决方案。

此外,我还有很多 Angular2 服务被降级。但问题仅在于注入到 .run 函数中使用的 Angular1 服务中的一个特定服务。

【问题讨论】:

    标签: angularjs angular typescript upgrade downgrade


    【解决方案1】:

    您可以使用此处描述的解决方法https://github.com/angular/angular/issues/10992: 将你的运行代码放入setTimeout函数中。

    angular.module('app.test', ['app'])
    ...
        .run(($injector) => {
            setTimeout(function() {
               var angularNg1Service = $injector.get('angularNg1Service');
               angularNg1Service.doSmth();
               // downgraded angularNg2Service is available here
               // inside of async function that will run after module.run method
               var angularNg2Service = $injector.get('angularNg2Service');
            },0);
        });
    

    为确保应用程序状态在配置应用程序之前不会启动(在运行方法中执行),您可以为每个状态添加解析。

    angular.module('app.test', ['app'])
        .config(($stateProvider) => 
            $stateProvider.state('base', {
                url: '/',
                controller: 'TestStateCtrl',
                resolve: {
                    appBootstrapped: ['appBootstrapStateService', () => {
                        return appBootstrapStateService.statePromise;
                    ]},
                    authenticationCheck: ['angularNg1Service', 'appBootstrapped', (angularNg1Service, appBootstrapped) => {
                        angularNg1Service.test1();
                    }]
                }
            })
        })
    

    为了让它正常工作,你应该在 module.run 方法结束时更改引导状态

    angular.module('app.test', ['app'])
        ...
        .run(($injector) => {
            setTimeout(function() {
                ...
                var appBootstrapStateService = $injector.get('appBootstrapStateService');
                appBootstrapStateService.complete(); // allow state work
            },0);
        });
    

    appBootstrapStateService 类似于 angularJS 服务

    angular.module('app')
        .service('appBootstrapStateService', function () {
            const stateSubject = new Rx.Subject();
            this.statePromise = stateSubject.asObservable().toPromise();
    
            this.complete = () => {
                stateSubject.complete();
            };
        });
    

    【讨论】:

    • 欢迎来到 Stack Overflow!虽然这在理论上可以回答问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 2017-08-14
    相关资源
    最近更新 更多