html5ファイルのアップロード用のカスタム入力コンポーネントを作成しましたが、トークンを定義する必要があります。私はどこでそれを定義するか分からない。Angular2のカスタム入力 - トークンを定義する必要があります
import { Component, Provider, forwardRef } from '@angular/core';
import { CORE_DIRECTIVES, NG_VALUE_ACCESSOR } from '@angular/common';
function makeProvider(type) {
return new Provider(
NG_VALUE_ACCESSOR, {
useExisting: forwardRef(() => type),
multi: true,
});
}
@Component({
selector: 'file-input',
template: `
<div class="file-form">
<div
class="drop-zone"
(dragover)="dragover = true"
(dragleave)="dragover = false"
(drop)="handleFiles($event); $event.preventDefault();"
[ngClass]="{'dragover':dragover}"
>
Drop file here
</div>
<input type="file" (change)="handleFiles($event)" id="fileup"> <label for="fileup" class="button">Upload File</label>
<br>
<progress value="{{progress}}" max="100"></progress>
</div>
`,
directives: [CORE_DIRECTIVES],
providers: [makeProvider(FileInputComponent)],
host: {
'(fileChange)': 'onChange($event)',
},
})
export class FileInputComponent {
constructor() {
this.progress = 0;
this._value = '';
this.onChange =() => {};
this.onTouched =() => {};
this.ngControl.valueAccessor = this;
}
get value() {
return this._value;
}
set value(v) {
if (v !== this._value) {
this._value = v;
this.onChange(v);
}
}
writeValue(value) {
this._value = value;
this.onChange(value);
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
ngOnInit() {
if (!(window.File && window.FileList && window.FileReader)) {
alert('html5 file upload not available!');
}
// Prevent file drops anywhere to load the file as current page
window.addEventListener('dragover', (event) => {
event.preventDefault();
}, false);
window.addEventListener('drop', (event) => {
event.preventDefault();
}, false);
}
setValue(value) {
this.image = value;
}
handleFiles(event) {
event.preventDefault();
event.stopPropagation();
const files = event.target.files || event.dataTransfer.files;
const formData = new FormData();
formData.append('file', files[0]);
const xhr = new XMLHttpRequest();
// upload failed
xhr.addEventListener('error', (event) => {
console.warn('File upload failed');
}, false);
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
this.progress = Math.round((e.loaded * 100)/e.total);
}
}, false);
// uploadComplete
xhr.upload.addEventListener('load', (event) => {
this.progress = 0;
this.dragover = false;
}, false);
xhr.open('POST', 'http://localhost:3000/api/files'); // identifier vom file ist `file`
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
xhr.onreadystatechange = (event) => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const fileObj = JSON.parse(xhr.responseText || {});
fileObj.type = files[0].type;
this.onChange(fileObj);
} else {
console.warn(`File upload failed: ${xhr.responseText}`);
}
}
};
xhr.send(formData);
}
}
ViewWrappedException {_wrapperMessage: "Error in ./FormComponent class FormComponent - inline template:34:3", ... _context : DebugContext _originalException : BaseException _originalStack : "Error: Token must be defined!↵ at new BaseException... _wrapperMessage : "Error in ./FormComponent class FormComponent - inline template:34:3" _wrapperStack : "Error: Error in ./FormComponent class FormComponent - inline template:34:3↵ ... context
問題を解決たぶん、あなたは、あまりにも、そのコンポーネントのテンプレートを示すことができましたか? – rinukkusu