TypeError:不能作为函数调用类

在Angular 1.x应用上使用ES6,Angular Linter和Babel进行传输。 我收到这个错误:“类型错误:不能调用类作为一个函数”在控制台中,虽然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">"

最好我可以告诉,语法是正确的。 我最好的猜测是Babel转换到ES5,具体来说这是:

function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}

这里是源代码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;

以下是loginNotifyService与之交互的控制器:

'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;

LMK如果需要进一步澄清或提供信息,并感谢您的任何建议。


我可以通过将工厂更改为服务来解决此问题。 由于我从这种棉绒里设置了一条短绒规则,它最初被设定为工厂:

https://github.com/Gillespie59/eslint-plugin-angular

具体规则如下:

https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/no-service-method.md
(我必须禁用此特定规则才能使工厂更改为服务)

loginNotifyService代码的结构需要是一个服务才能正常工作(因为它是当前写入的)。 通过阅读这篇文章,我能够更清楚地了解两者之间的区别:

AngularJS:工厂和服务?

例:

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);

另外,感谢@罗登的回应和见解!


这似乎是一个'理解'的错误,AngularJS不会实例化一个'经过编译的'服务类,除非'看到'它是一个es6类(如下面的调用代码所示)。

由babel编译的类不是类,而是作为类的函数,因此babel会创建一些检查(此函数为: _classCallCheck ),以防止将类作为函数调用 (因为它们只应使用new关键字“调用”)。

invoke函数中的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 = /^classb/.test(stringifyFn(func));
  }
  return result;
}

未能检测到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))();
}

而且你会得到一个"TypeError: Cannot call a class as a function"错误。

编辑 :我再次看看这个代码,你可能会声明一个这样的类来完成这个工作:

class Foo {
 static get $$ngIsClass(){return true;}
}

这将强制isClass返回true,并且将使用new关键字调用它。 (如果你可以测试和确认它的工作原理,我将不胜感激)。

链接地址: http://www.djcxy.com/p/77983.html

上一篇: TypeError: Cannot call a class as a function

下一篇: Navigate to another view via $state.go