简体   繁体   中英

Angular access to “this” of controlled class from directive scope

I implemented angular project with es6 style like this :

controller.js

export default class InsertController {

    constructor($scope) {
        this.$scope =$scope;
        this.data=[];
    }

    fillGrid(data) {

        console.log(data);

    }


}
InsertController.$inject = ['$scope'];

Directive.js

import angular from 'angular';

function FanGrid($compile) {
    return {

        replace: true,
        restrict: 'E',
        transclude: true,
        link: function (scope, element, attrs) {

            //I want access to fillGrid method of controller
            scope.fillGrid(data);


        }

    }
}

export default angular.module('directives.fanGrid', [])
    .directive('fanGrid', FanGrid)
    .name;

Now I want to know

  1. How to access and call fillGrid() method of controller in directive
  2. How to acess to "this" of controller class from directive

You can make the controller belong to the directive itself, so they have a shared scope.

import angular from 'angular';
import directiveController from 'directive.controller.js';

export default () => ({
  bindToController: {
    someBinding: '='
  },
  replace: true,
  restrict: 'E',
  link: function (scope, element, attrs) {

    // To access a method on the controller, it's as simple as you wrote:
    scope.vm.fillGrid(data);

  },
  scope: true,
  controller: directiveController,
  controllerAs: 'vm'
});

Then your controller is as you wrote it:

export default class directiveController {

  constructor($scope) {
    this.$scope = $scope;
    this.data = [];
  }

  fillGrid(data) {
    console.log(data);
  }
}

If you use ES6 in angular1, you'd better implement a directive like this:

class FanGridController {
    constructor() {
        this.fillGrid('some data') //Output some data
    }
}

function FanGridDirective($compile) {
    return {
        replace: true,
        restrict: 'E',
        transclude: true,
        controller: "FanGridController",
        scope: {
            fillGrid: "=?fillGrid",
            controllerThis: "=?controllerThis"
        }
        link: function(scope, element, attrs) {
            //I want access to fillGrid method of controller
        },
        controllerAs: "vm",
        bindToController: true
    }
}

export { FanGridController, FanGridDirective }

With this implementation, the this is pointed to 'vm' in FanGridController . the vm is a attribute of $scope object. And all variables in the scope:{} can be accessed by this

The answer to your question is that you can make the fillGrid and controllerThis as a scope parameter and pass it in HTML template. Then call this method with this.fillGrid .

export default class InsertController {
    constructor($scope) {
        this.$scope = $scope;
        this.data = [];
    }

    fillGrid(data) {
        console.log(data);
    }
}
InsertController.$inject = ['$scope'];

Pass the parameter in HTML

<fan-grid fill-grid="vm.fillGrid" controller-this="vm"></fan-grid>

Then call the method and access the controller's this in directive controller:

class FanGridController {
    constructor() {
        let controllerThis = this.controllerThis; 
        this.fillGrid('some data'); //Output some data
    }
}

or in link function:

link: function(scope, element, attrs) {
    let controllerThis = $scope.vm.controllerThis;
    $scope.vm.fillGrid('some data') //Output some data
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM