7

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!

2
  • You're using hasFocus:@ which takes the true/false values as strings. You need to get them as objects using hasFocus:"=" and has-focus="true" on the HTML Commented Jan 8, 2015 at 15:14
  • Thanks Omri - Thats great - worked perfectly, yes got confused with the isolate scope options! Commented Jan 16, 2015 at 9:07

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.