Angular2自定义输入 - 必须定义令牌

时间:2016-07-20 09:44:17

标签: typescript angular

我已经为html5文件上传创建了一个自定义输入组件,但是我得到并且错误地告诉我必须定义令牌。我不知道在哪里定义它。

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:&#34; ./FormComponent类错误   FormComponent - 内联模板:34:3&#34;,...   _context:DebugContext   _originalException:BaseException   _originalStack:&#34;错误:必须定义令牌!↵新的BaseException ...   _wrapperMessage:&#34; ./FormComponent类中的错误FormComponent - 内联模板:34:3&#34;   _wrapperStack:&#34;错误:./FormComponent类中的错误FormComponent - 内联模板:34:3↵... context

2 个答案:

答案 0 :(得分:1)

我终于找到了解决方案

使用makeProvider功能无效

使用

const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR = new Provider(
    NG_VALUE_ACCESSOR, {
        useExisting: forwardRef(() => FileInputComponent),
        multi: true,
    });

并添加

providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR],

解决了问题

答案 1 :(得分:0)

我认为NG_VALUE_ACCESSOR现在是@angular/forms模块的一部分:

import { NG_VALUE_ACCESSOR } from '@angular/forms';