我是角的新手。我试图从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也不会显示任何错误。
我扩展了@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!!!
};
这是对其他一些模型的改进,数据将以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();
});
}
};
});
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-if或ng-switch)时,目标委托(输入)还没有呈现也会工作
http://api.jquery.com/on/
最简单的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()">
类似于这里的其他一些很好的答案,我写了一个指令来解决这个问题,但是这个实现更紧密地反映了附加事件的角度方式。
你可以像这样使用指令:
HTML
<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);
}
};
}]);