【问题标题】:Can I use an Angular es5 controller with a new es6 service using babel and grunt?我可以使用带有 babel 和 grunt 的新 es6 服务的 Angular es5 控制器吗?
【发布时间】:2017-02-16 05:39:39
【问题描述】:

我想在我的 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 以在开发时更新更改)所以我想知道我做错了什么..

【问题讨论】:

    标签: angularjs ecmascript-6 babeljs


    【解决方案1】:

    你忘记了new

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

    在这种情况下,Angular 将无法从 $inject 属性中受益,您需要对代码进行 ng 注释,因为它可以解决:

    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,并在旧版本的 angular (1.3) 上导致此错误消息。

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

    【讨论】:

    • 感谢您的帮助!!我会尝试一下,真的希望投票支持你的答案
    • 另外,此代码.service('Info', $http =&gt; new InfoService($http)) 不正确,因为箭头不能是构造函数。
    • @estus 箭头只是一种表达方式 - 将 $http 作为参数并返回其构造函数使用 $http 参数的新 InfoService .....
    • 不幸的是,我什至添加了“新”或尝试使用“ngInject”注释和“angular.module('app').service('Info', InfoService);'的其他方式它没有帮助:(我会阅读链接帖子也许会有所帮助
    • @lironn servicenew 实例化一个函数。箭头不能更新,使用有错误。这可能起作用的唯一原因是箭头被 Babel 转换为正常功能。相同的代码在原生 ES6 上会失败。无论如何,答案是正确的。
    【解决方案2】:

    所以我找到了一种让它工作的方法,但我不太喜欢它.. 我将 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'
                }]
            },
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-03
      • 2017-04-29
      • 2018-10-26
      • 2015-04-04
      • 2020-05-29
      • 1970-01-01
      • 2016-02-29
      • 1970-01-01
      相关资源
      最近更新 更多