Daan Geerdink
Daan Geerdink

Reputation: 33

Setting a scope variable from a directive with AngularJS

I've gone through what must be 20 similar questions asked on SO but have yet to find a solution for my situation, so I hope you guys can help me out.

The goal is to sort the list of names by the property that's provided in the "sort-type" attribute of the directive, but only for the list within each controller (not all lists at the same time).

HTML

<div ng-controller="TestController as testOne">
   <b>By:</b> {{testOne.sortType}}<br>
   <b>Reverse:</b> {{testOne.sortReverse}}<br>
   <div ng-repeat="item in testOne.list">
       <p table-sort sort-type="name" sort-reverse="false"><a href="#">Sort by name</a></p>
       <ul>
           <li ng-repeat="childItem in testOne.childList | orderBy:testOne.sortType">{{childItem.name}}</li>
       </ul>
   </div>
</div>

<br><br>

<div ng-controller="TestController as testTwo">
   <b>By:</b> {{testTwo.sortType}}<br>
   <b>Reverse:</b> {{testTwo.sortReverse}}<br>
   <div ng-repeat="item in testTwo.list">
       <p table-sort sort-type="name" sort-reverse="false"><a href="#">Sort by name</a></p>
       <ul>
           <li ng-repeat="childItem in testTwo.childList | orderBy:testTwo.sortType">{{childItem.name}}</li>
       </ul>
   </div>
</div>

Javascript (Angular)

var app = angular.module('demo', []);

app.controller('TestController', TestController);

function TestController() {
    var vm = this;

    vm.sortType    = 'oldOrder';
    vm.sortReverse = false;

    vm.list      = [1];
    vm.childList = [{ name: 'Jimmy' },
                    { name: 'Danny' },
                    { name: 'Bobby' }];
}

/////////////////////////////////////

app.directive('tableSort', tableSort);

function tableSort() {

    var directive = {
        restrict: 'A',
        link: linkFunc,
    };

    return directive;

    function linkFunc(scope, element, attr) {
        element.on('click', function() {
            if(scope.sortType === attr.sortType) {
                scope.sortReverse = !scope.sortReverse;
            } else {
                scope.sortType = attr.sortType;
            }
        });
    }

}

JSFiddle here

My actual application is a bit more complex but I've tried to abstract it as much as possible.

Thanks for looking :)

Upvotes: 3

Views: 80

Answers (1)

Dayan Moreno Leon
Dayan Moreno Leon

Reputation: 5435

Ok Several things going on here:

  1. you are using the controllerAs syntax on your templates but you are changing scope variables in your directive. hence your controller variables are never changed.

  2. your directive is inside of the ng-repeat which means that you are actuating actually on a child scope so if you are setting variables directive on the scope your ng-repeat won't be able to reach them because they are being set after the child scope are created.

  3. you are using element.on which executes outside of angular digest which means you would have to call scope.$apply to let angular know that something happened.

Take a look at this https://jsfiddle.net/rez8ey12/

i hope it helps

Upvotes: 1

Related Questions