[英]Can I use an Angular es5 controller with a new es6 service using babel and grunt?
I want to start using ES6 (2015) in my Angular 1.3 + grunt stack without refactoring the entire existing ES5 code, (or switching grunt with other tool..) But when trying to use a new ES6 service from an "old" controller I'm getting following error, 我想在我的Angular 1.3 + grunt堆栈中开始使用ES6(2015),而不重构整个现有的ES5代码,(或使用其他工具切换grunt。)。但是,当尝试从“旧”控制器使用新的ES6服务时,出现以下错误,
" Cannot read property '1' of null at Function.annotate [as $$annotate] .... " “无法在Function.annotate [作为$$ annotate] ...处读取null的属性'1'。
The babel configuration in grunt: 咕bel咕ba的巴别塔配置:
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'
}]
}
},
The service code: 服务代码:
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));
The use in es5 controller: 在es5控制器中的使用:
angular.module('app').controller('SomeCtrl',
function ComposerCtrl(Info) {
Info.getInfo();
});
The transpiled ES5 InfoService was generated under .tmp/app (and I configured grunt watch to update changes while developing) so I wonder what am I doing wrong.. 编译的ES5 InfoService是在.tmp / app下生成的(我配置了grunt watch以在开发时更新更改),所以我想知道我在做什么错。
You have forgotten about new
: 您忘记了new
:
...
angular.module('app').service('Info', $http => new InfoService($http))
In this case, angular will not benefit from $inject
property and you will need to ng-annotate your code, as it solves to: 在这种情况下,角度不会从$inject
属性中受益,您需要对代码进行ng注释,因为它可以解决:
angular.module('app').service('Info', function($http) { return new InfoService($http); });
The simpler solution it to replace service definition with: 用以下更简单的解决方案替换服务定义:
angular.module('app').service('Info', InfoService);
Angular's DI will use $inject
property and add new
operator for you. Angular的DI将使用$inject
属性并为您添加new
运算符。
It is worth noting, that TypeScript users had the same problem: How can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope? 值得注意的是,TypeScript用户遇到了同样的问题: 如何使用不会污染全局范围的TypeScript类来定义AngularJS服务?
EDIT: 编辑:
It is possible, that you are using wrong controller expression (for example unclosed ng-controller
attribute: 您可能使用了错误的控制器表达式(例如,未关闭的ng-controller
属性:
<div .... ng-controller="SignupFormController as signupFormCtrl>
This messes up angular and leads to this error message on older versions of angular (1.3). 这会弄乱angular并导致在旧版本的angular(1.3)上出现此错误消息。
More info about issue: https://github.com/angular/angular.js/issues/10875 有关问题的更多信息: https : //github.com/angular/angular.js/issues/10875
So I've found a way to make it work but I don't like it so much.. I configured the babel to dist the files at the same place my *.es6.js files and updated the index.html so Angular will load the es5 transpiled file (InfoService.js), and when I debug I do it on the es6 file (I guess it relates to the sourceMap) 因此,我找到了一种使它工作的方法,但是我不太喜欢它。.我配置了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'
}]
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.