Reputation: 883
What i am trying to do:
I am creating a directive with input text field. Also taking value and a onChange method as scope parameter. A controller is wraped over this directive as u see in the html, this controller provides implementation of onChange method and a model for value.
Issue i am facing:
see line console.log($scope.data)
: This statement prints the older value of data object in the console.
Any guess why it is happening.
JS codde
angular.module('APP', [])
.directive('txtInput', function () {
return {
restrict: "E",
replace: true,
scope: {
value: '=',
onChange: '&',
},
template:
'<div>'+
'<input type="text" '+
'ng-change = "onChange()" '+
'ng-model="value" />'+
'</div>',
}
})
.controller('pageCtrl', function($scope) {
$scope.data = {
userPost: "sdsds",
}
$scope.onPostInputChange = function() {
console.log($scope.data)
}
})
Here is the HTML
<div ng-app='APP' ng-controller="pageCtrl">
<txt-input
value="data.userPost"
on-change="onPostInputChange()"> </txt-input>
</div>
Also check the copy at JSFIDDLE
Upvotes: 4
Views: 152
Reputation: 48968
This is a common problem when using both two-way =
binding and expression &
binding in directives and components with isolate scope. Two-way binding
uses a watcher which transfers values from isolate scope to parent scope. The dirty-checking and execution of the watchers happens after any invocation of the expression binding. There is a delay between when the expression executes and when the value is transfered to the parent scope.
The solution is to expose the value as a local when the expression binding is invoked. Any expression will then have that value available immediately instead of waiting for a digest cycle.
angular.module('APP', [])
.directive('txtInput', function () {
return {
restrict: "E",
replace: true,
scope: {
value: '=',
onChange: '&',
},
template:
'<div>'+
'<input type="text" '+
//'ng-change = "onChange()" '+
//expose value as a local
'ng-change = "onChange({$value: value}) '+
'ng-model="value" />'+
'</div>',
}
})
HTML
<div ng-app='APP' ng-controller="pageCtrl">
<txt-input
value="data.userPost"
on-change="onPostInputChange($value)">
</txt-input>
</div>
In the parent controller, use the value furnished as an argument to the function:
angular.module('APP').controller('pageCtrl', function($scope) {
$scope.data = {
userPost: "sdsds",
}
$scope.onPostInputChange = function(value) {
//console.log($scope.data)
console.log(value);
}
})
The DEMO in JSFiddle
Upvotes: 3