我可以使用带有babel和grunt的新es6服务的Angular es5控制器吗?

时间:2016-10-07 09:09:56

标签: angularjs ecmascript-6 babeljs

我想在我的Angular 1.3 + grunt堆栈中开始使用ES6(2015)而不重构整个现有的ES5代码,(或者用其他工具切换grunt ......) 但是当试图从“旧”控制器使用新的ES6服务时,我遇到了错误,

“无法读取null的属性'1'     在Function.annotate [as $$ annotate] ....“

grunt中的babel配置:

        babel: {
        options: {
            sourceMap: true,
            presets: ['es2015']
        },
        dist: {
            files: [{
                expand: true,
                cwd: '<%= yeoman.app %>',
                src: '**/*.es6.js',
                dest: '.tmp/app',
                ext: '.es5.js'
            }]
        },
        test: {
            files: [{
                expand: true,
                cwd: 'test/spec',
                src: '{,*/}*.es6.js',
                dest: '.tmp/spec',
                ext: '.es5.js'
            }]
        }
    },

服务代码:

class InfoService {
    constructor($http) {
      this.$http = $http;
    }

    getInfo() {
        console.log('getting');
        return this.$http.get('/backend/something/readAll');
    }
}

InfoService.$inject = ['$http'];

angular.module('app').service('Info', $http => InfoService($http));

在es5控制器中使用:

angular.module('app').controller('SomeCtrl', 
function ComposerCtrl(Info) {
    Info.getInfo();
});

转换后的ES5 InfoService是在.tmp / app下生成的(我在开发时配置了grunt watch来更新更改)所以我想知道我做错了什么..

2 个答案:

答案 0 :(得分:1)

您忘记了new

...
angular.module('app').service('Info', $http => new InfoService($http))

在这种情况下,angular不会从$inject属性中受益,您需要对代码进行ng-annotate,因为它解决了:

angular.module('app').service('Info', function($http) { return new InfoService($http); });

用以下方法替换服务定义的简单解决方案:

angular.module('app').service('Info', InfoService);

Angular的DI将使用$inject属性并为您添加new运算符。

值得注意的是,TypeScript用户遇到了同样的问题: How can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope?

修改

您可能使用了错误的控制器表达式(例如未闭合的ng-controller属性:

 <div .... ng-controller="SignupFormController as signupFormCtrl> 

这会弄乱角度,并在旧版本的angular(1.3)上导致出现此错误消息。

有关问题的更多信息: https://github.com/angular/angular.js/issues/10875

答案 1 :(得分:0)

所以我找到了一种让它工作的方法,但我不太喜欢它。 我将babel配置为在我的* .es6.js文件的相同位置对文件进行远程处理并更新index.html以便Angular将加载es5转换文件(InfoService.js),当我调试时我在es6文件上执行此操作(我猜它与sourceMap有关)

        babel: {
        options: {
            sourceMap: true,
            presets: ['es2015']
        },
        dist: {
            files: [{
                expand: true,
                src: '**/*.es6.js',
                ext: '.js'
            }]
        },