Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Custom directive change attribute value

Struggling to find out the best way to watch for attribute changes, which would ideally update based on a keypress event, bound to the scope in the parent controller

I would like each 'instance' of the directive to have its own 'hasFocus' property to be changed by updating the attribute value e.g.

<menu has-focus="{{ true }}" ></menu>
<menu has-focus="{{ false }}" ></menu>
<menu has-focus="{{ false }}" ></menu>

template:

<div class="menu">
<ul>
    <li ng-repeat="option in menu.options" ng-class="{ 'focused' : hasFocus  }" tabindex="{{ $index }}">
        <div class="icon">{{ $index+1 }}</div>
    </li>
</ul>

and so only 1 directive can have the value equal to 'true' at any one time.

I have a custom directive

.directive('menu', function()
{
  restrict : 'E',
  templateUrl : 'partials/menu-left.html',
  replace : true,
  scope : {
        hasFocus : '@'
  },
  link : function( $scope, element, attrs )
  {
    attrs.$observe('hasFocus', function(value) {
        console.log(value);
     });
  }

}) 

but cant seem to extract the value from the $observe method tried using $watch but still didnt work not sure what I am doing wrong!

like image 566
SteveP124 Avatar asked Jan 08 '15 14:01

SteveP124


1 Answers

if you use the @ binding, you might have to use $watch like this:

$scope.$watch(function(){
   return attrs.hasFocus;
}, function(val) {
     $scope.hasFocus = val;
});

if that doesn't work, or if you prefer two-way binding with =:

<menu has-focus="true" ></menu>

and

.directive('menu', function()
{
  restrict : 'E',
  templateUrl : 'partials/menu-left.html',
  replace : true,
  scope : {
        hasFocus : '='
  },
  link : function( $scope, element, attrs )
  {
    // $scope.hasFocus holds true/false
  }

}) 

I think two-way binding is better especially with booleans because if you only need it to control how the DOM looks, you might not even need to watch for a change, you'd just have to plug in $scope.hasFocus into the DOM somewhere (ng-show, ng-switch, etc.)

EDIT: yes, I just noticed your template, so if you use two-way binding (=) you don't need the watch

like image 88
benri Avatar answered Nov 07 '22 11:11

benri