如何检查文件输入字段的变化?

我是角的新手。我试图从HTML“文件”字段读取上传的文件路径,每当“更改”发生在这个字段上。如果我使用“onChange”,它可以工作,但当我以angular的方式使用“ng-change”时,它就不起作用了。

<script>
var DemoModule = angular.module("Demo",[]);
DemoModule .controller("form-cntlr",function($scope){
$scope.selectFile = function()
{
$("#file").click();
}
$scope.fileNameChaged = function()
{
alert("select file");
}
});
</script>


<div ng-controller="form-cntlr">
<form>
<button ng-click="selectFile()">Upload Your File</button>
<input type="file" style="display:none"
id="file" name='file' ng-Change="fileNameChaged()"/>
</form>
</div>

fileNameChaged ()从不调用。Firebug也不会显示任何错误。

339352 次浏览

没有文件上传控件的绑定支持

https://github.com/angular/angular.js/issues/1375

<div ng-controller="form-cntlr">
<form>
<button ng-click="selectFile()">Upload Your File</button>
<input type="file" style="display:none"
id="file" name='file' onchange="angular.element(this).scope().fileNameChanged(this)" />
</form>
</div>

而不是

 <input type="file" style="display:none"
id="file" name='file' ng-Change="fileNameChanged()" />

你能试试吗?

<input type="file" style="display:none"
id="file" name='file' onchange="angular.element(this).scope().fileNameChanged()" />

注意:这要求angular应用程序始终在调试模式中。如果调试模式被禁用,这将在产品代码中不起作用。

和在你的函数改变 而不是< / p >

$scope.fileNameChanged = function() {
alert("select file");
}

你能试试吗?

$scope.fileNameChanged = function() {
console.log("select file");
}
下面是一个文件上传的工作示例,拖放文件上传可能会有帮助 http://jsfiddle.net/danielzen/utp7j/ < / p >

Angular文件上传信息

在ASP中上传AngularJS文件的URL。网

https://github.com/geersch/AngularJSFileUpload

AngularJs原生多文件上传与NodeJS的进展

http://jasonturim.wordpress.com/2013/09/12/angularjs-native-multi-file-upload-with-progress/

ngUpload - AngularJS中使用iframe上传文件的服务

http://ngmodules.org/modules/ngUpload

简单的方法是写你自己的指令绑定到“change”事件。 只是让你知道IE9不支持FormData,所以你不能真正从change事件中获得文件对象

你可以使用ng-file-upload库,它已经支持IE和FileAPI polyfill,并简化将文件发布到服务器。它使用一个指令来实现这一点。

<script src="angular.min.js"></script>
<script src="ng-file-upload.js"></script>


<div ng-controller="MyCtrl">
<input type="file" ngf-select="onFileSelect($files)" multiple>
</div>

JS:

//inject angular file upload directive.
angular.module('myApp', ['ngFileUpload']);


var MyCtrl = [ '$scope', 'Upload', function($scope, Upload) {
$scope.onFileSelect = function($files) {
//$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $files.length; i++) {
var $file = $files[i];
Upload.upload({
url: 'my/upload/url',
data: {file: $file}
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
}
}
}];

我做了一个小指令来监听文件输入的变化。

查看JSFiddle

view.html:

<input type="file" custom-on-change="uploadFile">

controller.js:

app.controller('myCtrl', function($scope){
$scope.uploadFile = function(event){
var files = event.target.files;
};
});

directive.js:

app.directive('customOnChange', function() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var onChangeHandler = scope.$eval(attrs.customOnChange);
element.on('change', onChangeHandler);
element.on('$destroy', function() {
element.off();
});


}
};
});

这是对其他一些模型的改进,数据将以ng模型结束,这通常是你想要的。

标记(只要创建一个属性数据文件,这样指令就可以找到它)

<input
data-file
id="id_image" name="image"
ng-model="my_image_model" type="file">

JS

app.directive('file', function() {
return {
require:"ngModel",
restrict: 'A',
link: function($scope, el, attrs, ngModel){
el.bind('change', function(event){
var files = event.target.files;
var file = files[0];


ngModel.$setViewValue(file);
$scope.$apply();
});
}
};
});

类似于这里的其他一些很好的答案,我写了一个指令来解决这个问题,但是这个实现更紧密地反映了附加事件的角度方式。

你可以像这样使用指令:

超文本标记语言

<input type="file" file-change="yourHandler($event, files)" />

如您所见,您可以将所选择的文件注入到事件处理程序中,就像您将$event对象注入到任何ng事件处理程序中一样。

Javascript

angular
.module('yourModule')
.directive('fileChange', ['$parse', function($parse) {


return {
require: 'ngModel',
restrict: 'A',
link: function ($scope, element, attrs, ngModel) {


// Get the function provided in the file-change attribute.
// Note the attribute has become an angular expression,
// which is what we are parsing. The provided handler is
// wrapped up in an outer function (attrHandler) - we'll
// call the provided event handler inside the handler()
// function below.
var attrHandler = $parse(attrs['fileChange']);


// This is a wrapper handler which will be attached to the
// HTML change event.
var handler = function (e) {


$scope.$apply(function () {


// Execute the provided handler in the directive's scope.
// The files variable will be available for consumption
// by the event handler.
attrHandler($scope, { $event: e, files: e.target.files });
});
};


// Attach the handler to the HTML change event
element[0].addEventListener('change', handler, false);
}
};
}]);

我建议创建一个指令

<input type="file" custom-on-change handler="functionToBeCalled(params)">


app.directive('customOnChange', [function() {
'use strict';


return {
restrict: "A",


scope: {
handler: '&'
},
link: function(scope, element){


element.change(function(event){
scope.$apply(function(){
var params = {event: event, el: element};
scope.handler({params: params});
});
});
}


};
}]);

这个指令可以使用很多次,它使用自己的作用域,不依赖于父作用域。你也可以给handler函数一些参数。处理函数将与作用域对象一起调用,该对象在您更改输入时处于活动状态。 $apply在每次更改事件被调用

时更新你的模型

最简单的Angular jqLite版本。

JS:

.directive('cOnChange', function() {
'use strict';


return {
restrict: "A",
scope : {
cOnChange: '&'
},
link: function (scope, element) {
element.on('change', function () {
scope.cOnChange();
});
}
};
});

HTML:

<input type="file" data-c-on-change="your.functionName()">

我扩展了@Stuart Axon的想法,为文件输入添加双向绑定(即允许通过将模型值重置为null来重置输入):

app.directive('bindFile', [function () {
return {
require: "ngModel",
restrict: 'A',
link: function ($scope, el, attrs, ngModel) {
el.bind('change', function (event) {
ngModel.$setViewValue(event.target.files[0]);
$scope.$apply();
});


$scope.$watch(function () {
return ngModel.$viewValue;
}, function (value) {
if (!value) {
el.val("");
}
});
}
};
}]);

Demo

太完整的解决方案基于:

`onchange="angular.element(this).scope().UpLoadFile(this.files)"`

隐藏输入字段并将其替换为图像的简单方法,在解决方案之后,这也需要对angular进行hack,但可以完成工作[TriggerEvent不像预期的那样工作]

解决方案:

  • 将输入字段放入display:none[输入字段存在于DOM中但不可见]
  • 在后面放置你的图像 在图像上使用nb-click()激活一个的方法

当图像被点击时,在输入字段上模拟一个DOM动作“点击”。果不其然!

 var tmpl = '<input type="file" id="\{\{name}}-filein"' +
'onchange="angular.element(this).scope().UpLoadFile(this.files)"' +
' multiple accept="\{\{mime}}/*" style="display:none" placeholder="\{\{placeholder}}">'+
' <img id="\{\{name}}-img" src="\{\{icon}}" ng-click="clicked()">' +
'';
// Image was clicked let's simulate an input (file) click
scope.inputElem = elem.find('input'); // find input in directive
scope.clicked = function () {
console.log ('Image clicked');
scope.inputElem[0].click(); // Warning Angular TriggerEvent does not work!!!
};

我这样做过;

<!-- HTML -->
<button id="uploadFileButton" class="btn btn-info" ng-click="vm.upload()">
<span  class="fa fa-paperclip"></span></button>
<input type="file" id="txtUploadFile" name="fileInput" style="display: none;" />
// self is the instance of $scope or this
self.upload = function () {
var ctrl = angular.element("#txtUploadFile");
ctrl.on('change', fileNameChanged);
ctrl.click();
}


function fileNameChanged(e) {
console.log(self.currentItem);
alert("select file");
}

这个指令也会传递选定的文件:

/**
*File Input - custom call when the file has changed
*/
.directive('onFileChange', function() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var onChangeHandler = scope.$eval(attrs.onFileChange);


element.bind('change', function() {
scope.$apply(function() {
var files = element[0].files;
if (files) {
onChangeHandler(files);
}
});
});


}
};
});

HTML的使用方法:

<input type="file" ng-model="file" on-file-change="onFilesSelected">

在我的控制器中:

$scope.onFilesSelected = function(files) {
console.log("files - " + files);
};

监听文件输入更改的另一种有趣方法是监视输入文件的ng-model属性。当然,FileModel是一个自定义指令。

是这样的:

HTML→<input type="file" file-model="change.fnEvidence">

JS代码->

$scope.$watch('change.fnEvidence', function() {
alert("has changed");
});

希望它能帮助到一些人。

使用ng-change1 < a href = " https://stackoverflow.com/a/43074638/5535245 " > < / >工作的“files-input”指令的工作演示

要使<input type=file>元素工作于ng-change指令,它需要一个与ng-model指令一起工作的自定义指令

<input type="file" files-input ng-model="fileList"
ng-change="onInputChange()" multiple />

演示

angular.module("app",[])
.directive("filesInput", function() {
return {
require: "ngModel",
link: function postLink(scope,elem,attrs,ngModel) {
elem.on("change", function(e) {
var files = elem[0].files;
ngModel.$setViewValue(files);
})
}
}
})


.controller("ctrl", function($scope) {
$scope.onInputChange = function() {
console.log("input change");
};
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
<h1>AngularJS Input `type=file` Demo</h1>
    

<input type="file" files-input ng-model="fileList"
ng-change="onInputChange()" multiple />
    

<h2>Files</h2>
<div ng-repeat="file in fileList">
\{\{file.name}}
</div>
</body>

Angular的元素(比如指令的根元素)都是jQuery [Lite]对象。这意味着我们可以像这样注册事件监听器:

link($scope, $el) {
const fileInputSelector = '.my-file-input'


function setFile() {
// access file via $el.find(fileInputSelector).get(0).files[0]
}


$el.on('change', fileInputSelector, setFile)
}

这是jQuery事件委托。在这里,监听器附加到指令的根元素。当事件被触发时,它将弹出到已注册的元素,jQuery将确定事件是否起源于匹配已定义选择器的内部元素。如果是,处理程序将触发。

这种方法的好处是:

  • 处理程序被绑定到$元素,当指令作用域被销毁时,$元素将被自动清除。
  • 模板中没有代码
  • 当你注册事件处理程序(比如使用ng-ifng-switch)时,即使目标委托(输入)还没有被呈现,也会工作。

http://api.jquery.com/on/

您可以简单地在onchange中添加以下代码,它将检测更改。你可以写一个函数在X点击或删除文件数据。

document.getElementById(id).value = "";