[SOUND] In this lecture, we're going to speak about 2-way, 1-way, and 1-time binding. The concept of 2-way and 1-way binding is something we've already seen. And the concept of 1-time binding is something we're going to explore in a bit more detail in this lecture. Then we'll compare and contrast these different binding strategies to each other. So you've seen this code before. The first line is an input element that has an ng-model defined on it with a name property. That's an example of 2-way binding. And what 2-way binding means is that not only this AngularJS set up a watcher for your name property that is sitting on the dollar sign scope. But it will also set up some sort of listener on the input element such that if the value of the input element changes, that change will be reflected in the name property on a dollar sign scope. So in that case, you're really affecting the name property in both ways. You can affect it by the user because they're typing things into the text box. And the $scope.main property gets updated. And likewise, if you update inside of your controller, the $name property, that value will get updated. And the UI, the browser, will get updated automatically which means that text box will display the new value that you updated inside of your controller. The second line has our regular interpolation with double curly braces. That's an example of 1-way binding. The only way this value will change in the browser is if something inside the controller will update the last name property on the $scope. There's no way for us to, at least directly through the double curly braces, affect the value of the last name from the browser from the user to the controller. So this is an example of 1-way binding. It shouldn't come as a surprise to you that if we set up a lot of these bindings, a lot of watchers will get created for us by Angular JS. Well, as you remember, the digest cycle goes through the entire list of every watcher that we have and checks for any changes that occurred in the last loop. Well, these loops can go for a few times. And if you have thousands of thousands of these watchers, obviously, that will take some time and therefore, the performance of your application will degrade. In fact, the rule of thumb is that you shouldn't have any more than 2,000 watchers per page. However, I've seen more than 2,000 and the app worked pretty well anyway, but it's kind of a rule of thumb. You could have more, you could have less depending obviously on, obviously, what type of machine the user is using, how fast it is, and how much it can handle. However, one thing is clear. Minimizing the number of live active watchers in your watchers list during the digest loop is something that is desirable. So one way to do that is set up a special, what's called a 1-time binding. The 1-time binding looks very similar to the 1-way binding, except in front of the property name you put double colons. What that tells Angular JS is that it should set up a watcher for this property. But the second this property gets initialized, the AngularJS digest cycle will kick in. It will update that property in our UI, will repaint the browser and the property will be seen to the user. And at that point, AngularJS will automatically remove the watcher for that particular property, so you'll have one less. Of course, the downside of that is, is this only happens one time. So if that property were to get updated in the course of your app, that update will not be reflected in your UI. However, for things like, let's say, fullname of a user, that is not expected to change throughout the life cycle of your application. Something that we still need to be able to somehow insert into our HTML template. But we don't need to watch that property and check that property every single time for the rest of the life of our application. Let's jump into the code editor and take a look at this concept in action. Okay, so I'm back in my editor and I'm located in lecture 16 folder which is located in fullstack-course 5 examples folder, and I'm looking at app.js. That's basically the same binding app that we had before with that binding controller, except we cleaned it up a little bit and changed a couple of things. So we have a couple of properties. The first one is firstName and I initialized that up front to Yaakov. The second one is fullName initialized to a empty string up front. We also have the function we've seen before which basically shows us the number of watchers we have in our digest cycle. And we're going to go ahead and look in into the Angular innards, so to speak, and look at the $$watchersCount and that will tell us how many watchers Angular has in its digest cycle. And we'll bind this function to a button so we could click it at any time and see how many watchers we have. Another one we have is setFullName. What that will do is it will take a property, fullName on the scope, and it will combine it firstName + and my last name, Chaikin. So that will update the fullName property. And we also have a couple of functions just for us to see what's going on behind the scenes, which basically log the firstName and also log the fullName. So the $scope,firstName, $scope,fullName. If we look in our index.html, we have, basically, a couple of buttons here that say showNumberOfWatchers and setFullName. setFullName is the thing that will set the full name to be the first name plus whatever that string that I added to it to be the last name, so basically my fullName. We also have a 1-time binding here for the fullName and a couple of buttons to log the FirstName and log the FullName. In addition, we'll also have an input element that has a 2-way binding setup using ng-model on our firstName property. Which means if we type something in here, the firstName property will keep getting updated as we type. Let's go ahead and take a look at that in our browser. So here's our log number of watchers, so if we click that right now, we'll see the number of watchers is 1. That should already give us a bit of a pause. Why is that? Well, we want this property fullName here to appear and there's only 1 watcher. Well, if we go back to our index.html, we'll see that for sure this creates a watcher. Which means that this did not create a watcher, or something else happened, because should have been two watchers. Well, let's take a look here. Let's go ahead and log the first name. That makes sense, Yaakov. That takes it right from here, and this actually took it before from our initialized property on $scope. And let's log the full name. The full name right now is an empty space. Well, that's easy, we could set the full name. Let's set the full name right there, and if we log the full name now, you see it is Yaakov Chaikin. It's the full name. The problem is, and this is still not showing up here at all, it's just an empty string. Why is that? Why is this happening? Well, part of the reason we kind of discussed, we didn't have an extra watcher that watched that fullName property to output this once it changed. Let's go back to our code and see if we could find the culprit for this problem. And if you look at the very front here, you'll see that we initialized our fullName already to an empty string. And that's where the culprit is. As I've told you before, the second the property that is 1-time bound gets initialized, that's when the Angular digest cycle goes ahead and loops over all the watchers and outputs this value to the browser and then removes the watcher for it. That means that the HTML template that has this property 1-time bound to it will never get updated again because the watcher is no longer there. So the way we can fix this is simply by commenting this line out. And that means that the very first time that this property will get initialized will be Inside of our setFullName function, which gets triggered by us pressing the button. So let's go ahead and save that. Let's go back to our browser. Let's click # of Watchers and now things look much better. Now there's 2 watchers. If we log the first name, it's Yaakov, log the full name, it's undefined, which is exactly how we want it at this point. Because if it was defined already, it would have been too late, the watcher would have been removed. So now if we click Set Full Name, you'll see it will appear right here, but if we click log # of Watchers again, it's no longer 2, it's 1. Because once we bounded 1-time bounded to our HTML template, we no longer need that watcher. We could save that performance and remove the watcher from our watchers list. So therefore, that is why we only have 1 here. Meanwhile, the 2-way binding will continue to work. So for example, if I log the full name right now, it's Yaakov Chaikin. But if I update the name, let's say, put AAA in here, that means that the firstName property in the scope would have gotten updated with an extra three letter As at the end. Which means that if I execute setFullName right now, it will make the fullName property be Yaakov with triple As, and then my last name Chaikin. That will not change what is displayed in our HTML template because that was a 1-time binding. However, the full name, if we reset the full name, as you can see here, the fullName property will actually contain the updated first name. Because that is something that we manually updated inside of our setFullName function, making the outside scope that full name the new value of the first name which was updated plus the string the last name. So let's summarize. The 2-way binding that is set up with the ng-model attribute on an input element means a couple of things. It means that Angular sets up a listener for change to the value on the input element and any change to that automatically gets updated to the property on the $scope. The second thing it means is that any direct update to the property, like inside of a controller, any direct update to the property value is automatically updated in UI as well. And obviously that's done using a watcher. 1-way binding on the other hand, automatically set up by double curly braces around the property, means only one thing. The direct update to the property value inside a controller or something similar is automatically updated in the UI and the watcher still stays. That's the contrast a 1-time binding which looks very similar to the 1-way binding that is set up with the double curly braces and double colons in front of the property name. And what that means is, the initialized value, not any value, but only the initialized value of a property, is automatically updated in the UI. And the watcher for that property is then automatically removed by Angular, so the user interface never gets updated with any updates to that property again.