0

I'm new to AngularJS and I want to change the behavior of a button dynamically.

As I am used to JQuery, I use element.attr('ng-click', 'controller.function()');

But, as I understood AngularJS needs to compile the new DOM. But, in my head "compile" = "cost".

What is the best practice :

  • Change/Add DOM elements then compile when needed.
  • Hide another button, and just show/hide the one I need.

Thank you !

ogdabou
  • 582
  • 1
  • 10
  • 41
  • 1
    [`ng-hide` and `ng-show` directives](http://stackoverflow.com/questions/12599637/angularjs-ng-show-ng-hide), or [`ng-switch`](http://docs.angularjs.org/api/ng/directive/ngSwitch) if you're switching between multiple elements. "The Angular way", as I understand it, is not to add or remove DOM elements explicitly at all, just show or hide them. – Blazemonger Mar 07 '14 at 15:30
  • 1
    You'd better have two different buttons and show necessary one at a time with `ng-show`. – dfsq Mar 07 '14 at 15:32

3 Answers3

3

I prefer to use ng-switch for these type of things. It ends up being much simpler and its always a good idea to make use of the existing angular directives where possible. Other developers working on your project will appreciate the simplicity.

http://jsfiddle.net/L9T6J/2/

the html...

<div ng-switch="state">
    <button ng-switch-when="0" ng-click="updateState()">Label 1</button>
    <button ng-switch-when="1" ng-click="updateState()">Label 2</button>
</div>

and the javascript...

$scope.state = 0;
$scope.updateState = function () {
    $scope.state = $scope.state === 0 ? 1 : 0;   
}
Charlie Martin
  • 8,208
  • 3
  • 35
  • 41
  • I choosed to use this ! As I am the first step on AngularJS of my team it's important if it is more understandable. Thank you all – ogdabou Mar 12 '14 at 09:37
2

i generally hand that type of thing in angular like so

markup

<button ng-click="myButton.actions[myButton.state]()">
    {{myButton.labels[myButton.state]}}
</button>

scope

$scope.myButton = {
    state: 0,        
    labels: ['label 1','label 2'],    
    actions: [
        function() {$scope.myButton.state = 1;},
        function() {$scope.myButton.state = 0;}
    ]
};

here is a fiddle to see it in action

http://jsfiddle.net/pixelchemist/L9T6J/

  • I like your answer because the state/behavior changement is a part of the button itself. It's working now with a boolean and ng-show but I think it is less clear in the code than this. Thank you, I'll try it :) – ogdabou Mar 07 '14 at 16:16
0

It depends entirely on the application and scope of the directive, I go either two ways:

  1. If it's between different buttons (if-elseif-else etc), the directive is very simple and explanatory by just looking at it, I use ng-if or ng-switch.

  2. If it's a complex directive that lives on its own, meaning it has its own scope and functions, there's no reason for it to be cluttering the DOM. For instance, if you search through the DOM a lot, you're going to be adding more data to search through, then instead if you destroy and rebuild it only when its used. It also clutters the DOM if you have tons of custom directives that you show/hide.

If your application has several heavy directives that contain complexity and you only use them after you click on a button, it makes more sense to create/destroy, than to hide/show the directive (helps if the directive contains data that it is getting from a service).

Also it just feels more right to invoke sub applications when you need them, rather than hiding/showing them, though this is a personal preference and I might be wrong.

The majority of custom directives you use from 3rd parties, they create/destroy their directive rather than show/hide.

Not entirely sure how the $watchers work with custom directive when hidden, but you removed that possibility when you create/destroy directives which helps with performance. For instance, if you render your HTML often, then $watchers pile up if you have a lot of ng-if/ng-switch, on the contrary, if you create/destroy, then when the html DOM is destroyed, Angularjs won't check the $watcher because it doesn't exist so you gain performance.

Samir Alajmovic
  • 3,247
  • 3
  • 26
  • 28