max*_*les 6 javascript notifications login angularjs babeljs
在Angular 1.x应用程序上工作,使用ES6,Angular Linter和Babel进行转换.我收到此错误:"TypeError:无法在控制台中调用类作为函数",虽然html加载得很好.
TypeError: Cannot call a class as a function
at _classCallCheck (bundle.js:97664)
at Object.loginNotifyService (bundle.js:97670)
at Object.invoke (bundle.js:23052)
at Object.enforcedReturnValue [as $get] (bundle.js:22885)
at Object.invoke (bundle.js:23052)
at bundle.js:22844
at getService (bundle.js:22993)
at injectionArgs (bundle.js:23018)
at Object.invoke (bundle.js:23044)
at $controllerInit (bundle.js:29012) "<div ui-view="" class="ng-scope">"
Run Code Online (Sandbox Code Playgroud)
我能说的最好,语法是正确的.我最好的猜测是Babel转向ES5,特别是:
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
Run Code Online (Sandbox Code Playgroud)
这是源JS:
'use strict';
class loginNotifyService {
constructor (notify) {
this.loginNotifyService = notify;
}
info (message, config) {
config = config || {};
config.message = message;
config.classes = 'alert alert-info ' + (config.classes || '');
return this.loginNotifyService(config);
}
warn (message, config) {
config = config || {};
config.message = message;
config.classes = 'alert alert-warning ' + (config.classes || '');
return this.loginNotifyService(config);
}
error (message, config) {
config = config || {};
config.message = message;
config.classes = 'alert alert-danger ' + (config.classes || '');
return this.loginNotifyService(config);
}
success (message, config) {
config = config || {};
config.message = message;
config.classes = 'alert alert-success ' + (config.classes || '');
return this.loginNotifyService(config);
}
notify (config) {
return this.loginNotifyService(config);
}
closeAll () {
return this.loginNotifyService.closeAll();
}
}
// loginNotifyService.$inject = ['notify'];
/* @ngInject */
export default loginNotifyService;
Run Code Online (Sandbox Code Playgroud)
这是loginNotifyService与之交互的Controller:
'use strict';
class loginController {
constructor ($state, loginNotifyService, loginService) {
this.$state = $state;
this.loginNotifyService = loginNotifyService;
this.loginService = loginService;
this.loginInProgress = false;
}
login () {
this.loginNotifyService.closeAll();
this.loginInProgress = true;
this.loginService.login(this.email, this.password).then(
() => {
this.loginInProgress = false;
this.$state.go('dashboard');
},
(error) => {
this.loginInProgress = false;
this.showErrors(error);
}
);
}
showErrors (error) {
this.errors = error;
this.loginNotifyService.error(error);
}
}
// loginController.$inject = ['$state', 'loginNotifyService', 'loginService'];
/* @ngInject */
export default loginController;
Run Code Online (Sandbox Code Playgroud)
LMK如果需要进一步澄清或信息,并感谢您的任何建议.
我能够通过将工厂更改为服务来解决此问题.由于我从这个linter设置的linting规则,它最初被设置为工厂:
https://github.com/Gillespie59/eslint-plugin-angular
以下是具体规则:
https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/no-service-method.md
(我必须禁用此特定规则才能从工厂更改为服务)
loginNotifyService代码的结构需要是一个服务才能正常工作(因为它是当前编写的).通过阅读这篇文章,我能够更清楚地理解两者之间的区别:
例:
angular
.module('commonModule', [
uiRouter,
cgNotify,
ngAnimate,
ngMaterial,
ngMessages,
ngSanitize,
ngAria,
'navRoute',
'mdTheme',
])
// ALL OF THE SERVICES BELOW WERE PREVIOUSLY FACTORIES.
// CHANGING "loginNotifyService" TO A SERVICE INSTEAD,
// FIXED THE "TypeError: Cannot call a class a function" ERROR!
.service('authService', authService)
.value('loginConfigService', loginConfigService)
.service('loginNotifyService', loginNotifyService)
.service('loginService', loginService)
.service('resetPassService', resetPassService)
.component('login', loginComponent)
.component('resetPass', resetPassComponent);
Run Code Online (Sandbox Code Playgroud)
另外,谢谢@Rhoden的回复和见解!
这似乎是一个“理解”错误,AngularJS 不会实例化“转换”(编译)服务类,除非它“看到”它是一个 es6 类(如下面的调用代码所示)。
babel 编译的类不是类,而是充当类的函数,因此 babel 创建了一些检查(这里是这个函数:)_classCallCheck以防止类被作为函数调用(因为它们只能用new关键字“调用”)。
AngularJS 在调用函数上使用以下代码:
function isClass(func) {
// Support: IE 9-11 only
// IE 9-11 do not support classes and IE9 leaks with the code below.
if (msie || typeof func !== 'function') {
return false;
}
var result = func.$$ngIsClass;
if (!isBoolean(result)) {
result = func.$$ngIsClass = /^class\b/.test(stringifyFn(func));
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
无法检测 babel 编译的类。所以,这个验证也失败了:
if (!isClass(fn)) {
// http://jsperf.com/angularjs-invoke-apply-vs-switch
// #5388
return fn.apply(self, args);
} else {
args.unshift(null);
return new (Function.prototype.bind.apply(fn, args))();
}
Run Code Online (Sandbox Code Playgroud)
然后你会得到一个"TypeError: Cannot call a class as a function"错误。
编辑:我再次查看了该代码,您可能可以声明一个这样的类来使其工作:
class Foo {
$$ngIsClass = true;
// or
static get $$ngIsClass = true;
}
Run Code Online (Sandbox Code Playgroud)
这将强制isClass返回 true,并且将使用new关键字调用。(如果您可以测试并确认它有效,我将不胜感激)。