Angular 1.x和EcmaScript 2015中的类和依赖注入

时间:2015-09-28 15:01:15

标签: angularjs ecmascript-2015

我使用babel,gulp和browserify来构建我的应用程序。

我有简单的控制器,像这样:

export default class MyCtrl() {
    constructor() {
    }

    someMethod() {
        // I know that this is not pure code, but it is not part of current question
        return $http.post('/api/some/url/', {some: 'data'});
    }
}

问题在于依赖注入(DI)。这在构造函数中使用'ng-annotate'很简单:

// @ngInject
constructor($http) {
    // $http is resolved here
}

但不使用其他方法:

// @ngInject
someMethod($http) {
    // FAIL. $http is resolved, because angular DI working only on main ctrl function
}

我找到了解决这个问题的4种不同方法:

// 1, using this
constructor($http) {
    this.http = $http;
}
someMethod() {
    this.http.get(...);
}

// 2, using WeekMap
var deps = new WeekMap()
class MyCtrl {
    constructor($http) {
        deps.set(this, {http: $http)
    }
    someMethod() {
        deps.get(this).http.get(...);
    }
}

// 3, using inherited class
class Injectable {
    constructor() {
        var injector = angular.element(document).injector();
        for (var prop in this) {
            let fn = this[prop];
            if(angular.isFunction(fn)) {
                this[prop] = function(...args) {
                    injector.invoke(fn, this, args);
                }
            }
        }
    }
}
class MyCtrl extends Injectable {
    constructor() {
        super()
    }
    someMethod($http) {
        $http.get(...)
    }
    // but then I can't use not injected values =(
    //someAnotherMethod(valueFromCtrl, $http) {
    //}
}

// 4, manually using injector

function di(...args) {
    var injector = angular.element(document).injector()
    if(args.length == 1) {
        return injector.get(args[0])
    }
    var ret = args.map( name => injector.get(name) )
    return args.length > 1 ? ret : ret[0];
}

class MyCtrl extends Injectable {
    constructor() {
    }
    someMethod($http) {
        var $http = di('$http');
        $http.get(...)
    }
}

1和2方法需要为每个依赖项提供大量代码。 3方法从控制器传递给方法的值有问题 我认为最好的方法是4号,但不确定是否还有其他问题。

问题是哪种方法更强大? 在ES clasess子方法中使用DI有什么最佳实践吗?

// UPD 方法1和2需要大量额外代码,例如对于工厂:

export default class SomeFactory {
    constructor($http) {
        this.$http = $http
    }

    getItems() {
        this.$http.get('/').then(console.log.bind(console))
    }

    static makeFactory($http) {
        return new SomeFactory($http)
    }
}

angular.module('someModule', []).factory(SomeFactory.makeFactory)

0 个答案:

没有答案