ES6 AngularJS指令<>服务沟通

时间:2015-10-20 14:06:46

标签: angularjs angularjs-directive

我认为我对js有范围问题。请看下面的代码。 这是我在es6中的AngularJS示例。我使用grunt browserify将代码编译为es5。

如果我打电话给我的例子我得到了错误: TypeError:this.gatewayServiceGet不是函数     在ChainsDirective.loadChains [as chainsServiceLoadChains]

我检查一下,发现 loadChains 中的 this 与构造函数中的 this 不一样。

我该怎么办?

这是我的app.js

'use strict';

import AppController from './appController.js';
import ChainsDirective from './components/chains/chains.directive.js';
import ChainsService from './components/chains/chains.service.js';
import GatewayService from './components/common/gateway/gateway.service.js';

angular
    .module('SalesCockpit', ['ui.router', 'ui.grid'])
    .config($stateProvider => {
        $stateProvider
            .state('chains', {
                url: '/chains',
                templateUrl: 'components/chains/chains.html'
            })
            .state('chainDetail', {
                url: '/chain/{chainId:int}/detail',
                templateUrl: 'components/chain-detail/chain-detail.html'
            })
        ;

    })
    .controller('AppController', AppController)
    .service('chainsService', ChainsService)
    .service('gatewayService', GatewayService)
    .directive('chains', ChainsDirective);

这是我的链指令

export default function ChainsDirective() {
    class ChainsDirective {

        /*@ngInject*/
        constructor(chainsService, $state) {
            this.chainsServiceLoadChains = chainsService.loadChains;
            this.gridOptions = {
                enableColumnMenus: false,
                columnDefs: [
                    {
                        name: 'id',
                        visible: false
                    },
                    {
                        name: 'name',
                        displayName: 'Kette',
                        cellTemplate: '<div class="ui-grid-cell-contents"><a ng-click="grid.appScope.openDetail(row.entity.id)">{{row.entity.name}}</a></div>'
                    }
                ]
            };
            this.$stateGo = $state.go;
            this.fetch();
        }

        /**
         * @param int chainId
         */
        openDetail(chainId) {
            this.$stateGo('chainDetail', {chainId})
        }

        fetch() {
            return this.chainsServiceLoadChains().then(data => {
                this.gridOptions.data = data
            })
        }
    }

    return {
        restrict: 'E',
        template: '<div id="chains" ui-grid="gridOptions" external-scopes="$scope" class="grid"></div>',
        controller: ChainsDirective,
        controllerAs: 'chains'
    }
}

这是我的连锁服务

export default class ChainsService {

    /*@ngInject*/
    constructor(gatewayService) {
        this.gatewayServiceGet = gatewayService.get;
    }

    /**
     * @returns Promise
     */
    loadChains() {
        return this.gatewayServiceGet('loadChains');
    }
}

1 个答案:

答案 0 :(得分:1)

FWIW,这与ECMAScript 2015无关.JavaScript始终如此。

this的值取决于函数如何调用。所以,如果你把它称为

this.chainsServiceLoadChains()
this内的

chainsServiceLoadChains将引用.之前的内容,即引用this实例的ChainsDirective

一种解决方案是将绑定函数的this值转换为特定值:

this.chainsServiceLoadChains = chainsService.loadChains.bind(chainsService);

现在,如何调用该函数并不重要,this将始终引用chainsService

详细了解this