Zach Schneider
Zach Schneider

Reputation: 315

Pass directive attribute into linked controller?

I have a directive i'm using to do the same search filtering across multiple pages. So the directive will be using a service and get pretty hefty with code. Because of that I want to link to a controller instead of have the controller inside the directive like this:

.directive('searchDirective', function($rootScope) {
    return { 
        restrict: 'E',
        templateUrl:'searchtemplate.html',
        controller: 'searchCtrl',
        controllerAs: 'search'
    };
});

I also want access to parent scope data inside the template, so I don't want to use a isolated scope.

Anyway here's what i'm not sure how to do. My directive looks like this:

<search-directive filter="foo"/>

How do I pass in the value in the filter attribute so that I can access it in my controller using $scope.filter or this.filter?

If I were using an isolated scope it'd be simple. If i had the controller in the same page I could use $attrs. But since i'm using a controller from another spot and don't want an isolated scope i'm not sure how to get the attrs values into the controller.

Any suggestions?

Upvotes: 2

Views: 1545

Answers (3)

Thomas
Thomas

Reputation: 12049

What about using the link function and passing the value to the scope?

return { 
        restrict: 'E',
        templateUrl:'searchtemplate.html',
        controller: 'searchCtrl',
        controllerAs: 'search',
        link: function (scope, element, attr) {
           scope.filter = attr.filter;
      }
    };

Upvotes: 1

Meligy
Meligy

Reputation: 36624

Flip the values of bindToController and scope around.

{
    ....
    scope: true,
    bindToController: { filter:'=' } 
    ...
}

I have just hit the same issue over the weekend, and made a simple complete example here: bindToController Not Working? Here’s the right way to use it! (Angular 1.4+)

Upvotes: 0

Leon Gaban
Leon Gaban

Reputation: 39044

searchDirective.js

angular
    .module('searchDirective', []).controller('SearchCtrl', SearchCtrl)
    .directive('SearchDirective', directive);

function directive () {
    var directive = {
        templateUrl:'searchtemplate.html',
        restrict: "E",
        replace: true,
        bindToController: true,
        controller: 'searchCtrl as search',
        link: link,
        scope: { filter:'=' } // <-- like so here
    };
    return directive;
    function link(scope, element, attrs) {}
}

SearchCtrl.$inject = [
    '$scope',
    '$filter'];

function SearchCtrl(
    $scope,
    $filter) {

    /** Init SearchCtrl scope */
    /** ----------------------------------------------------------------- */
    var vs = $scope;
    // ....

Also I highly recommend checking out this AngularJS style guide, how you are writing your directive above is how I use to do it too. John Papa shows some way better ways: https://github.com/johnpapa/angular-styleguide

Directives: https://github.com/johnpapa/angular-styleguide#directives

Controllers: https://github.com/johnpapa/angular-styleguide#controllers

Upvotes: 0

Related Questions