Pass Directive Isolate Scope Bindings to its Contr

2019-07-27 11:24发布

问题:

How to pass directive parameter to its controller?

I use directive:

<directive value="ctrl.item"></directive>

.directive('directive', [ function () {
    return {
        restrict: 'AE',
        scope: {
            value: '=value'
        },
        templateUrl: 'item.html',
        controller: 'Item as item'
    };
}])

I want to read value inside a directive's controller:

.controller('Item', [function Item () {

    console.log(this.value);
}])

Is it possible to do using this?

回答1:

Set the bindToController property to true

.directive('directive', [ function () {
    return {
        restrict: 'AE',
        scope: {
            value: '=value'
        },
        //USE bindToController
        bindToController: true,
        templateUrl: 'item.html',
        controller: 'Item as item'
    };
}])

bindToController

This property is used to bind scope properties directly to the controller. It can be either true or an object hash with the same format as the scope property.

When an isolate scope is used for a directive (see above), bindToController: true will allow a component to have its properties bound to the controller, rather than to scope.

After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller properties. You can access these bindings once they have been initialized by providing a controller method called $onInit, which is called after all the controllers on an element have been constructed and had their bindings initialized.

— AngularJS Comprehensive Directive API Reference


Use the $onInit life-cycle hook

.controller('Item', function Item () {
    this.$onInit = function() {    
        console.log(this.value);
    };
})

$compile:

Due to bcd0d4, pre-assigning bindings on controller instances is disabled by default. It is still possible to turn it back on, which should help during the migration. Pre-assigning bindings has been deprecated and will be removed in a future version, so we strongly recommend migrating your applications to not rely on it as soon as possible.

Initialization logic that relies on bindings being present should be put in the controller's $onInit() method, which is guaranteed to always be called after the bindings have been assigned.

— AngularJS Developer Guide - Migrating from V1.5 to V1.6



回答2:

It should be on your directive's scope, and you can access it inside the link method like so:

app.directive('directive', function () {
  return {
    restrict: 'AE',
    scope: {
        value: '='
    },
    templateUrl: 'item.html',
    link: function (scope, element, attrs) {
      console.log(scope.value);
    }
  };
});