Reputation: 1266
I'm in the middle of trying to get my head around the data binding capabilities of AngularJS and have sort of a newbie question:
In the sample below, when I type a name into the textbox, the greeting doesn't update.
<html ng-app>
<head>
<script src="js/angular.js"></script>
<script>
function myCtl($scope){
$scope.person=$scope.fname;
}
</script>
</head>
<body>
<div ng-controller="myCtl">
<input ng-model="fname"/>
<br/>
Hello, {{person}}
</div>
</body>
When I change
Hello, {{person}}
to
Hello, {{fname}}
The greeting updates as I type. I'm confused about why the second syntax works but not the first.
Upvotes: 2
Views: 942
Reputation: 364727
$scope.person=$scope.fname
creates a person
primitive property on the $scope object and assigns it the value undefined
(because $scope.fname does not yet exist when this line of code is executed). This is what your $scope looks like before you type into the textbox:
After you type something into the textbox, Angular automatically creates a fname
primitive property on the $scope, and automatic two-way databinding continually sets the value to whatever is in the textbox. So, if I type "Mark", then $scope now looks like this:
It should be clear now why {{person}}
shows nothing, but {{fname}}
shows what is in the textbox.
Upvotes: 4
Reputation: 14361
To asgoth's answer I would also add that this code belies a misunderstanding:
$scope.person=$scope.fname;
This code is not run each time something happens in the view but only once when your controller is executed. You seem to be trying to set $scope.person
to the value in $scope.fname
. But $scope.fname
is not defined - that's what your controller needs to do. Your view and controller are therefore both referencing an undefined value.
In a simple case like this your controller should just initialize your model when it starts:
function myCtl($scope){
scope.person = {
fname: '',
lname: '',
email: ''
};
}
and you then bind elements to properties of person (e.g. ng-model="person.fname"
).
Now, whenever code runs in your controller, it automatically has the correct person.fname
angular takes care of that for you - you never need to "read from your view".
function myCtl($scope){
$scope.person = {
fname: '',
lname: '',
email: ''
};
function validate() {
if (!$scope.email.match(/@/) return window.alert('Please enter a valid email address!');
}
}
From your view you would then do:
<form ng-submit="validate()">
or
<button ng-click="validate()">
Upvotes: 2
Reputation: 35829
Because, when you are typing in the input field, $scope.fname
is changing, not $scope.person
.
You could fix it with a $watch
on fname
:
$scope.$watch('fname', function(value) {
if(value) {
$scope.person = value;
}
}, true);
Upvotes: 2