I am binding an ng-model
to an input, but the value of the variable it's bound to is not being updated outside of the div
where that directive is declared:
<div input-field
ng-if="startTypes.selected.value == 'LocalDate' || startTypes.selected.value == 'LocalDateTime'">
<input id="date" type="text" ng-model="date" input-date>
<label for="date">Date</label>
Date inner scope: {{date}}
</div>
Date outer scope: {{date}}
When selecting a new date, ony the inner date
is updated. The outer one remains with the old value (which might be either undefined
or not depending if I declared it in the controller, it doesn't matter).
I am using angular-materialize, I am not sure if this is the source of the issue but it doesn't make sense because it is a specific framework for angular to work with the CSS framework materializecss.
This is the component I am using.
Edit:
I have tried declaring date
in the controller as $scope.date = new Date()
and indeed the current date is loaded in the date picker. However when a date is selected and the model changes, it's only updated locally (inner scope), while in the outer scope the old value remains.
As ng-if
creates a child scope which is Prototypically inherited from its current scope while inserting inner template to DOM, hence in this case ng-model
getting created inside ng-if
's child scope. So what happening is while creating a child scope
it carries the primitive
datatype values & reference
(object) datatypes values to child scope, thats why you can see the outer scope date
is getting value inside ng-if
date field(only first time). But when you update the value in date
you will not see the value gets updated to outer scope. Because the way child scope
has create primitive type
value not carry their references, where as objects are carried with their references. So you can create a object like $scope.model = {}
& then define a property into it, that will work. Because object are carried with their references to child scope, updating inner object would sync the outer object as well(they both are same). This rule is called as Dot Rule
by which you can fix your issue.
$scope.model = {};
$scope.model.date = new Date();
More convenient way to avoid such kind of scope hierarchy is using controllerAs
pattern while using controller on HTML. In this case you shouldn't be using $scope
instead you will bind all the properties to controller function context (this
). Thereafter when using controller you can use alias
of controller to get the values of controller like ng-controller="myCtrl as vm"
(here vm
is alias of controller which has all information binding to this
)
HTML
<div input-field
ng-if="vm.startTypes.selected.value == 'LocalDate' || vm.startTypes.selected.value == 'LocalDateTime'">
<input id="date" type="text" ng-model="vm.date" input-date>
<label for="date">Date</label>
Date inner scope: {{vm.date}}
</div>
Date outer scope: {{vm.date}}