Shannon Hochkins Shannon Hochkins - 18 days ago 5
AngularJS Question

How can i toggle directive without using scope declaration

I need to watch an attribute from a directive, and have that toggle a function whenever the value is true, this works the first time you click it, but i then need to reset the value of the ATTRIBUTE/Attribute model once it's evaluated, and that's the part i can't figure out.

DEMO OF ISSUE: https://jsfiddle.net/DG24c/200/

The desired outcome would be to have the

EXTERNAL ACCESS
button in my demo always trigger the alert method.

Template:

<div ng-controller="otherController">
<button interactive show-when="toggled">Show Directive Alert</button>
<button ng-click="toggled = true" >External access</button>
</div>


Javascript:

myApp.controller("otherController",function($scope){
$scope.toggled = false;
});


myApp.directive('interactive', function($parse) {
return {
restrict : 'A',
// scope : true || {} cannot be used
link : function(scope, element,attrs) {

element.on('click', function() {
show();
});

scope.$watch(attrs.showWhen, function(newValue,o) {
if (newValue) {
// the value is true, but now I need to reset
// the value on TOGGLED back to false here, so that the next
// time the button clicks, it will show the alert
show();
// tried attrs.$set('showWhen', false);
// tried var showAttr = $parse(attrs.showWhen)();
// showAttr = false;

}
});

function show() {
alert('showing!');
}
}
};
})

Answer

Try this:

$parse(attrs.showWhen + ' = false')(scope);

Demo: https://jsfiddle.net/DG24c/204/

Javascript:

myApp.directive('interactive', function($parse) {
  return {
    restrict : 'A',
    link : function(scope, element,attrs) {

       element.on('click', function() {
        show();
       });

       scope.$watch(function(inboundScope) {
           // gets the value of the attribute
           var interactive = $parse(attrs.showWhen)(inboundScope);
           if (!interactive) return false; // no need to continue if the value is already false
           $parse(attrs.showWhen + ' = false')(inboundScope); // updates parent scopes value back to false
           return interactive;           
       }, function(newValue) {
           if (newValue) show();
       });


       function show() {
           alert('showing!' + attrs.showWhen);
       }
    }
  };
});

HTML:

<div ng-app="myApp">
  <div ng-controller="myCtrl as $ctrl">
    <button interactive show-when="$ctrl.toggled">Show Directive Alert</button>
    <button ng-click="$ctrl.toggled = true" >External access</button>
    <pre>{{$ctrl.toggled | json}}</pre>

    <button interactive show-when="$ctrl.toggled2">Show Directive Alert2</button>
    <button ng-click="$ctrl.toggled2 = true" >External access2</button>
    <pre>{{$ctrl.toggled2 | json}}</pre>

  </div>
</div>
Comments