Javascript 使用 Angular Material 上传文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31867194/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
File Upload with Angular Material
提问by WreckingBall
I'm writing an web app with AngularJS and angular-material. The problem is that there's no built-in component for file input in angular-material. (I feel that file uploading doesn't fit the material design, but I need it in my app)
我正在用 AngularJS 和 angular-material 编写一个网络应用程序。问题是角度材料中没有用于文件输入的内置组件。(我觉得文件上传不符合材料设计,但我在我的应用程序中需要它)
Do you have a good solution for this problem?
你有解决这个问题的好方法吗?
采纳答案by WreckingBall
I find a way to avoid styling my own choose file button.
我找到了一种方法来避免样式化我自己的选择文件按钮。
Because I'm using flowjsfor resumable upload, I'm able to use the "flow-btn" directive from ng-flow, which gives a choose file button with material design style.
因为我使用flowjs进行可恢复上传,所以我可以使用ng-flow 中的“ flow-btn”指令,它提供了一个具有材料设计风格的选择文件按钮。
Note that wrapping the input element inside a md-button won't work.
请注意,将 input 元素包装在 md-button 中是行不通的。
回答by Radin Reth
Nice solution by leocaseiro
leocaseiro很好的解决方案
<input class="ng-hide" id="input-file-id" multiple type="file" />
<label for="input-file-id" class="md-button md-raised md-primary">Choose Files</label>
View in codepen
在代码笔中查看
回答by rynop
For Angular 6+:
对于 Angular 6+:
HTML:
HTML:
<input #csvInput hidden="true" type="file" onclick="this.value=null" (change)="csvInputChange($event)" accept=".csv"/>
<button mat-flat-button color="primary" (click)="csvInput.click()">Choose Spreadsheet File (CSV)</button>
Component method:
组件方法:
csvInputChange(fileInputEvent: any) {
console.log(fileInputEvent.target.files[0]);
}
Note:This filters to just allow .csv
files.
注意:此过滤器仅允许.csv
文件。
回答by Artyom Pranovich
Another example of the solution.
Will look like the following
CodePen link there.
CodePen 链接在那里。
<choose-file layout="row">
<input id="fileInput" type="file" class="ng-hide">
<md-input-container flex class="md-block">
<input type="text" ng-model="fileName" disabled>
<div class="hint">Select your file</div>
</md-input-container>
<div>
<md-button id="uploadButton" class="md-fab md-mini">
<md-icon class="material-icons">attach_file</md-icon>
</md-button>
</div>
</choose-file>
.directive('chooseFile', function() {
return {
link: function (scope, elem, attrs) {
var button = elem.find('button');
var input = angular.element(elem[0].querySelector('input#fileInput'));
button.bind('click', function() {
input[0].click();
});
input.bind('change', function(e) {
scope.$apply(function() {
var files = e.target.files;
if (files[0]) {
scope.fileName = files[0].name;
} else {
scope.fileName = null;
}
});
});
}
};
});
Hope it helps!
希望能帮助到你!
回答by Juniper
Based on this answer. It took some time for me to make this approach working, so I hope my answer will save someone's time.
基于这个答案。我花了一些时间让这种方法起作用,所以我希望我的回答能节省一些人的时间。
Directive:
指示:
angular.module('app').directive('apsUploadFile', apsUploadFile);
function apsUploadFile() {
var directive = {
restrict: 'E',
templateUrl: 'upload.file.template.html',
link: apsUploadFileLink
};
return directive;
}
function apsUploadFileLink(scope, element, attrs) {
var input = $(element[0].querySelector('#fileInput'));
var button = $(element[0].querySelector('#uploadButton'));
var textInput = $(element[0].querySelector('#textInput'));
if (input.length && button.length && textInput.length) {
button.click(function (e) {
input.click();
});
textInput.click(function (e) {
input.click();
});
}
input.on('change', function (e) {
var files = e.target.files;
if (files[0]) {
scope.fileName = files[0].name;
} else {
scope.fileName = null;
}
scope.$apply();
});
}
upload.file.template.html
上传.文件.模板.html
<input id="fileInput" type="file" class="ng-hide">
<md-button id="uploadButton"
class="md-raised md-primary"
aria-label="attach_file">
Choose file
</md-button>
<md-input-container md-no-float>
<input id="textInput" ng-model="fileName" type="text" placeholder="No file chosen" ng-readonly="true">
</md-input-container>
回答by Chris L
from jameswyse at https://github.com/angular/material/issues/3310
来自 jameswyse 在https://github.com/angular/material/issues/3310
HTML
HTML
<input id="fileInput" name="file" type="file" class="ng-hide" multiple>
<md-button id="uploadButton" class="md-raised md-primary"> Choose Files </md-button>
CONTROLLER
控制器
var link = function (scope, element, attrs) {
const input = element.find('#fileInput');
const button = element.find('#uploadButton');
if (input.length && button.length) {
button.click((e) => input.click());
}
}
Worked for me.
为我工作。
回答by Dombi Soma
Another hacked solution, though might be a little cleaner by implementing a Proxy button:
另一个被黑的解决方案,虽然通过实现代理按钮可能会更干净一些:
HTML:
HTML:
<input id="fileInput" type="file">
<md-button class="md-raised" ng-click="upload()">
<label>AwesomeButtonName</label>
</md-button>
JS:
JS:
app.controller('NiceCtrl', function ( $scope) {
$scope.upload = function () {
angular.element(document.querySelector('#fileInput')).click();
};
};
回答by MoA
You can change the style by wrapping the input inside a label and change the input display to none. Then, you can specify the text you want to be displayed inside a span element. Note: here I used bootstrap 4 button style (btn btn-outline-primary). You can use any style you want.
您可以通过将输入包装在标签内并将输入显示更改为无来更改样式。然后,您可以指定要在 span 元素内显示的文本。注意:这里我使用了 bootstrap 4 按钮样式(btn btn-outline-primary)。您可以使用任何您想要的样式。
<label class="btn btn-outline-primary">
<span>Select File</span>
<input type="file">
</label>
input {
display: none;
}
回答by Ismail Moukafih
File uploader with AngularJs Material and a mime type validation:
带有 AngularJs Material 和 mime 类型验证的文件上传器:
Directive:
指示:
function apsUploadFile() {
var directive = {
restrict: 'E',
require:['ngModel', 'apsUploadFile'],
transclude: true,
scope: {
label: '@',
mimeType: '@',
},
templateUrl: '/build/html/aps-file-upload.html',
controllerAs: 'ctrl',
controller: function($scope) {
var self = this;
this.model = null;
this.setModel = function(ngModel) {
this.$error = ngModel.$error;
ngModel.$render = function() {
self.model = ngModel.$viewValue;
};
$scope.$watch('ctrl.model', function(newval) {
ngModel.$setViewValue(newval);
});
};
},
link: apsUploadFileLink
};
return directive;
}
function apsUploadFileLink(scope, element, attrs, controllers) {
var ngModelCtrl = controllers[0];
var apsUploadFile = controllers[1];
apsUploadFile.inputname = attrs.name;
apsUploadFile.setModel(ngModelCtrl);
var reg;
attrs.$observe('mimeType', function(value) {
var accept = value.replace(/,/g,'|');
reg = new RegExp(accept, "i");
ngModelCtrl.$validate();
});
ngModelCtrl.$validators.mimetype = function(modelValue, viewValue) {
if(modelValue.data == null){
return apsUploadFile.valid = true;
}
if(modelValue.type.match(reg)){
return apsUploadFile.valid = true;
}else{
return apsUploadFile.valid = false;
}
};
var input = $(element[0].querySelector('#fileInput'));
var button = $(element[0].querySelector('#uploadButton'));
var textInput = $(element[0].querySelector('#textInput'));
if (input.length && button.length && textInput.length) {
button.click(function(e) {
input.click();
});
textInput.click(function(e) {
input.click();
});
}
input.on('change', function(e) {
//scope.fileLoaded(e);
var files = e.target.files;
if (files[0]) {
ngModelCtrl.$viewValue.filename = scope.filename = files[0].name;
ngModelCtrl.$viewValue.type = files[0].type;
ngModelCtrl.$viewValue.size = files[0].size;
var fileReader = new FileReader();
fileReader.onload = function () {
ngModelCtrl.$viewValue.data = fileReader.result;
ngModelCtrl.$validate();
};
fileReader.readAsDataURL(files[0]);
ngModelCtrl.$render();
} else {
ngModelCtrl.$viewValue = null;
}
scope.$apply();
});
}
app.directive('apsUploadFile', apsUploadFile);
html template:
html模板:
<input id="fileInput" type="file" name="ctrl.inputname" class="ng-hide">
<md-input-container md-is-error="!ctrl.valid">
<label>{@{label}@}</label>
<input id="textInput" ng-model="ctrl.model.filename" type="text" ng-readonly="true">
<div ng-messages="ctrl.$error" ng-transclude></div>
</md-input-container>
<md-button id="uploadButton" class="md-icon-button md-primary" aria-label="attach_file">
<md-icon class="material-icons">cloud_upload</md-icon>
</md-button>
Exemple:
例子:
<div layout-gt-sm="row">
<aps-upload-file name="strip" ng-model="cardDesign.strip" label="Strip" mime-type="image/png" class="md-block">
<div ng-message="mimetype" class="md-input-message-animation ng-scope" style="opacity: 1; margin-top: 0px;">Your image must be PNG.</div>
</aps-upload-file>
</div>
回答by fahimeh ahmadi
html:
<div class="upload">
<span>upload image</span>
<input
#Image
type="file"
(change)="handleFileInput($event.target.files)"
accept=".jpg,.svg,.png,.jpeg"
/>
<img
width="100%"
height="100%"
*ngIf="imageUrl"
[src]="imageUrl"
class="image"
/>
</div>
app.component.ts
app.component.ts
export class AppComponent {
options = [{ value: "This is value 1", checked: true }];
statuses = ["control"];
// name = "Angular";//
fileToUpload: any;
imageUrl: any;
handleFileInput(file: FileList) {
this.fileToUpload = file.item(0);
//Show image preview
let reader = new FileReader();
reader.onload = (event: any) => {
this.imageUrl = event.target.result;
};
reader.readAsDataURL(this.fileToUpload);
}
}