我远不是Angular的专家,所以我必须尝试在这里提问。我已经添加了在AngularJS项目中上传文件的可能性。我需要在用户提交表单之前在文本框(或最好是只读字段)中显示所选文件名。它包含许多需要验证的字段。问题是,所选的文件名永远不会出现。选择文件后,文本块仍为空。我尝试过以下代码(Plunker:http://plnkr.co/edit/Ll3GZdpp8Tsqwvo0W1ax):
的index.html:
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8" />
<title>Custom Plunker</title>
<script data-require="jquery@2.1.3" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<link data-require="bootstrap@*" data-semver="3.3.2" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
<script data-require="bootstrap@*" data-semver="3.3.2" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body ng-controller="MyCtrl">
<div class="row">
<div class="col-md-12">
<span class="btn btn-default btn-file">
Välj fil... <input type="file" onchange=" angular.element(this).scope().setFile(this) ">
</span>
<input type="text" ng-model="organizationSettings.logotypeFileName" />
</div>
</div>
</body>
</html>
app.js:
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.organizationSettings = {};
$scope.setFile = function(element) {
$scope.fileToUpload = element.files[0];
console.log($scope.fileToUpload.name);
$scope.organizationSettings.logotypeFileName = $scope.fileToUpload.name;
};
});
的CSS:
.btn-file {
position: relative;
overflow: hidden;
}
.btn-file input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 100px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
答案 0 :(得分:2)
原因是你正在使用onchange
,这是任何角度指令之外的事件。
每当您使用角度超出更改范围的事件时,您需要通知使用$apply
最简单的解决方法是使用ng-change
而不是原生onchange
。所有角度事件处理指令都将在内部触发$apply
替代方案(不是最好的方法)是保持改变并做:
$scope.setFile = function(element) {
$scope.fileToUpload = element.files[0];
console.log($scope.fileToUpload.name);
$scope.organizationSettings.logotypeFileName = $scope.fileToUpload.name;
$scope.$apply();
};
答案 1 :(得分:1)
我认为绑定更改可以更轻松,我将在下面解释如何执行此操作。通过将ng-model设置为输入,它将自动将输入控件绑定到控制器范围中定义的变量。因此,如果指定新文件,它将自动更新模型$ scope.fileToUpload。反过来说:在JS中完成的$ scope.fileToUpload中的任何更改都将反映在DOM中。
index.html - 尝试替换
<input type="file" onchange=" angular.element(this).scope().setFile(this) ">
带
<input type="file" ng-model="fileToUpload">
在app.js中,你可以摆脱:
$scope.setFile = function(element) {
$scope.fileToUpload = element.files[0];
console.log($scope.fileToUpload.name);
$scope.organizationSettings.logotypeFileName = $scope.fileToUpload.name;
};
答案 2 :(得分:1)
您无法使用ng-change进行文件上传,因为angularjs中的文件上传不支持绑定,这是angularjs中的一个问题。
在其他情况下,当您使用ng-change
(文件上传除外)时,您必须使用ng-model
使ng-change指令工作,以便根据它触发更改(所以只有你在使用它时会得到"Error: No controller: ngModel"
。
最好的解决方案是手动触发$scope.$apply()
以便以编程方式设置它来绑定输入模型。