I'm very new at angularjs and I'm in trouble,
I have html like this:
<section class="content" ng-app="offer">
<div ng-controller="OfferController">
...
<input name="Attachment" type="file" class="file_up" onchange="angular.element(this).scope().change(this)" ng-model="Attachment" />
<span>{{Attachment}}</span> //i can't get it
...
</div>
</section>
and script:
var myApp = angular.module('offer', []);
myApp.controller('OfferController', ['$scope', function ($scope) {
$scope.change = function (element) {
if (element.files.length > 0) {
$scope.Attachment = element.files[0].name;
}
else {
$scope.Attachment = "";
}
console.log($scope.Attachment); // I can get changed value in console
}
}]);
image:
I can get changed value in console but I can't get in html side when input's value change. Thank you so much in advance for any help.
I'm very new at angularjs and I'm in trouble,
I have html like this:
<section class="content" ng-app="offer">
<div ng-controller="OfferController">
...
<input name="Attachment" type="file" class="file_up" onchange="angular.element(this).scope().change(this)" ng-model="Attachment" />
<span>{{Attachment}}</span> //i can't get it
...
</div>
</section>
and script:
var myApp = angular.module('offer', []);
myApp.controller('OfferController', ['$scope', function ($scope) {
$scope.change = function (element) {
if (element.files.length > 0) {
$scope.Attachment = element.files[0].name;
}
else {
$scope.Attachment = "";
}
console.log($scope.Attachment); // I can get changed value in console
}
}]);
image:
I can get changed value in console but I can't get in html side when input's value change. Thank you so much in advance for any help.
Share Improve this question asked Aug 20, 2014 at 16:20 Engin ÜstünEngin Üstün 1,12811 silver badges18 bronze badges 02 Answers
Reset to default 6Since you change model from outside Angular's digest cycle, you have to inform framework manually that it must run watchers again. You can use $scope.$apply()
for this:
$scope.change = function (element) {
if (element.files.length > 0) {
$scope.Attachment = element.files[0].name;
}
else {
$scope.Attachment = "";
}
$scope.$apply();
}
Or more concise:
$scope.change = function(element) {
$scope.$apply(function() {
$scope.Attachment = element.files.length ? element.files[0].name : '';
});
}
Demo: http://plnkr.co/edit/6quQlHJIvdD3QwtOhHrB?p=preview
EDIT: As @dfsq pointed out in a ment, ng-change
doesn't work out of the box for a file input, so I edited to include an alternative solution instead.
You could write a custom directive to handle a file input yourself, and make it update the property binding in ng-model
(only one-way though).
.directive('input', function () {
return {
restrict: 'E',
require: '?ngModel',
link: function(scope, element, attr, ctrl) {
if (!ctrl || attr.type !== 'file') {
return;
}
var listener = function() {
var file = element[0].files[0];
var value = file && file.name;
if (ctrl.$viewValue !== value) {
scope.$apply(function() {
ctrl.$setViewValue(value); // update ng-model
});
}
};
element.on('change', listener);
}
}
})
This way, the onchange
or ng-change
is not needed, when user choose a file, the file name should be set to the property in ng-model
right away.
<input type="file" name="Attachment" ng-model="Attachment" ng-change="change()" />
<span>{{ Attachment }}</span>
Example Plunker: http://plnkr.co/edit/K3ZLoqNUPbo991b9ooq3?p=preview
Original answer: (this doesn't work for input type="file")
Instead of onchange
, you should use ng-change
instead.
Try changing this:
onchange="angular.element(this).scope().change(this)"
To this:
ng-change="change($event.target)"
Hope this helps.