We are going to study the differences between ngShow and ngIf. Our current setup is a controller with properties attached to this, because we are using the controller as syntax. For the experiment, we also have a primitive attached to the scope. It refers to the node.syntax here and there.
We have a directive. Whenever its link function is executed, we have a log there, and it listens to the broadcasts sent from the controller.
Here, we can toggle the different sections, ngShow and ngIf. Here, it's the raw template, so that's why you can see everything now. We have a form wrapping all the inputs below, and we want to check its validity.
One fundamental difference between ngShow and ngIf is their results on the DOM. The div in which I used ngShow does exist, but it has an ngHide class, which basically hides it. The div on which I put the ngIf doesn't exist at all.
If ever I toggle the ngShow section, it basically only removes the ngHide class. If I toggle the ngIf section, it now appears inside my DOM, the div and all its children.
An immediate difference can be noticed whenever I hit the run with JS button. We have a first log which matches the directive wrapped within the ngShow, but we have no log concerning the directive wrapped within the ngIf.
We can confirm that because if ever I hit broadcast, the event is received by the directive wrapped within the ngShow, and not from the one wrapped in the ngIf. No matter the visibility of the ngShow, it gets executed once, and then it listens to events. Basically, it's on.
Concerning the directive within the ngIf section, if I click and the ngIf section appears, we have the directive triggered, so we have the log. Basically, if I check/uncheck, each time this coding within the link function will be executed.
Now, if I broadcast, I have my listener within the directive, within the ngIf. If ever I hide the ngIf section, now whenever I broadcast, only the directive within the ngShow will receive the events.
Now, we'll see ngShow and ngIf doesn't behave the same when it comes to their scope. ngShow has the same scope as the surrounding templates, so here's the controller, but ngIf creates its own.
We'll notice that thanks to the node.syntax value here, which is attached to the scope, thanks to prototype or inheritance, this value is propagated to the ngIf scope. If ever I start changing the value, it's properly provided. But if ever I change the value from the ngIf scope there, you'll notice that everything is lost.
It has been the cause for many confusions within Angular, and it led to first the DOT syntax recommendations and, finally, to the controller as syntax. Concerning the DOT syntax, you can see we have an object with its properties, and both inputs are bound to it. This lets you ensure that changes are provided as expected.
Our last use case is form validating. Basically, so far we can see our form is invalid, but we have nothing displayed, which could be confusing for the user. If we toggle the ngShow section, we have our required field there, and we can fill in. Now, the form becomes valid.
If ever we toggle the ngIf section, it adds the required field there. As a result, the full form becomes invalid. If we toggle again, the required field from the ngIf has disappeared, and the form is valid again. If we show the ngIf section and fill in the required field, our form is valid.
Many people wonder whether they should use ngShow or ngIf. My personal take is to use ngIf, unless you have a good reason among those I tried to expose.