ES6类和Babel的角度服务

时间:2015-09-03 19:46:10

标签: angularjs ecmascript-6 angular-services

我正在尝试将ES6类用作Angular服务,但是当它被实例化时,方法无法访问构造函数变量。

class dataWrapperService {

    constructor($q, $log) {
        this.$q = $q;
        this.$log = $log;
    }

    data() {
        console.log(this.$q);
    }
}

dataWrapperService.$inject = ['$q', '$log'];

app.service('dataWrapper', dataWrapperService);

一旦Angular注入了服务并且我在其上调用了data方法,该方法就无法访问构造函数值。

// calling the data method results in an error
dataWrapper.data();   //TypeError: Cannot read property '$q' of undefined

//  console.log output of dataWrapper:
Object
  $log: Object
  $q: Q(resolver)
  __proto__: smDataWrapperService
    constructor: smDataWrapperService($q, $log)
    data: data()
    __proto__: Object

但是...

我可以手动 dataWrapperService,并且运行正常。

var dataWrapper = new smDataWrapperService("hello", "sir");
dataWrapper.data();   // "hello"

我在这里缺少什么?

更新

这似乎只发生在承诺回调中:

我通常将函数传递给然后/ catch ,如下所示:

$http.get('whatever').then(dataWrapper.data);

但只有以下方法才有效:

$http.get('whatever').then((response) => smDataWrapper.data(response))

3 个答案:

答案 0 :(得分:3)

Angular需要app.factory('dataWrapper', dataWrapperService);的函数,而不是类。

您可以向班级添加静态工厂方法,并将其添加到app.factory。 (请参阅下面的更新代码段)

这样的代码应该有效:

class dataWrapperService {

    constructor($q, $log) {
        this.$q = $q;
        this.$log = $log;
    }

    data() {
        console.log(this.$q);
    }

    static dataWrapperFactory($q, $log) {
        dataWrapperService.instance = new dataWrapperService($q, $log);
        return dataWrapperService.instance;
    }
}

dataWrapperService.$inject = ['$q', '$log'];

app.factory('dataWrapper', dataWrapperService.dataWrapperFactory);

<强>更新

正如评论中提到的,您的代码应该可以工作,因为ES6类是一个构造函数,而angular.service期待的是什么。

我稍后会检查您的代码是否有任何其他问题。

答案 1 :(得分:2)

我知道这已经很晚了,但也许有人会像我一样偶然发现这个类似问题,所以......

实际上,它与承诺无关。当你这样做时:

let function1 = () => {}
let function2 = function1

实际上,this对象对于函数是不同的。因此,当您尝试.then(function1)时,实际上function1正被复制到参数successCallback并且其this已更改。

但是,当您使用.then(() => function1())时,successCallback会收到您的lambda,this的实际function1也不会丢失。

所以如果你不知道,你做了什么从不在javascript中为函数分配函数,请改用lambdas

答案 2 :(得分:0)

使用Angular 1.6.4时,我在尝试注入某个控制器中定义为类的服务时收到错误。

  

无法将类作为函数调用

相反,我希望将一个函数用作服务。为了保持尽可能干净,我将导出一个立即返回实例化匿名类的函数。并在单独的文件中执行此操作并导入并使用该函数在另一个文件中创建服务。

由于您要求将ES6与Babel一起使用,请使用babel-plugin-angularjs-annotate通过在导出的函数上方添加'/* @ngInject */'来安全地注入依赖项。

注入的服务$q$log或通过闭包可用于类。 (无需在构造函数中传递它们并分配给它。)

// dataWrapperService.js
/* @ngInject */
export const dataWrapperService = ($q, $log) => new class {
  constructor() {
    // do stuff
  }

  data() {
    // $q available through closure
    console.log($q)
  }
}()

// in your.module.js
import angular from 'angular'

import { dataWrapperService } from './dataWrapperService'

export const YourModule = angular
  .module('yourmodule', [])
  .factory('dataWrapper', dataWrapperService)
  .name