在使用Angular1 + ES6时,控制器功能中的依赖注入未定义,控制器作为类

jac*_*All 5 javascript dependency-injection angularjs ecmascript-6

我使用ES6类来定义我的控制器,所以这是语法,

export class SearchBarController {
    constructor($log) {
        'ngInject';

        $log.debug("Hello");
    }

    textTyped($log){

        $log.debug("change fired.");
    }
} 
Run Code Online (Sandbox Code Playgroud)

观点:

<input type="text" data-ng-model="vm.txt" data-ng-change="vm.textTyped()"/>
Run Code Online (Sandbox Code Playgroud)

所以构造函数中的"Hello"记录正常.但是,在typedText()函数中"触发更改"没有触发,因为显然未定义如何使我的类函数textTyped()访问$ log服务?

注意:如果我将$ log分配给构造函数中的类属性,比如

this.logger = $log;
Run Code Online (Sandbox Code Playgroud)

然后呢,

this.logger.debug("Change fired.");
Run Code Online (Sandbox Code Playgroud)

这很有效.但我不确定这是否是正确的方法.

更新:此外,此方法将对$ log服务的引用公开给绑定到此控制器的视图.这有害吗?

有更好的解决方案吗?

jac*_*All 2

如果有人感兴趣,我使用 ES6 对象解构找到了一个更优雅的解决方案:

class ABCController {
    constructor($log, $http){
        let vm = this;
        vm.DI = () => ({$log, $http});
    }

    classFn(){
        let vm = this;
        let {$log, $http} = vm.DI();
        //Now use $log and $http straightway

        $log.debug("Testing");
        $http({...}).then();
    }

    classFn2(){
        let vm = this;
        //you can also destructure only the required dependencies in this way
        let {$http} = vm.DI();
    }
}
ABCController.$inject = ['$log', '$http'];
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您不需要编写丑陋/令人困惑的代码,例如 vm.DI.log 等。此外,通过这种方式,DI 在视图中暴露得更少。