2017-04-05 13 views
1

私はcropper.jsに基づいたイメージエディタであり、ユーザーは通常のファイル入力を介してイメージを「アップロード」するため、値をプログラムで提供するカスタムコントロールを作成しました。 File APIを使用してイメージをカスタムコントロールに割り当てます。ここ角2、カスタムコントロールがダーティーとしてマークされることはありません

import { 
    Component, 
    OnInit, 
    ViewChild, 
    ElementRef, 
    ViewEncapsulation, 
    forwardRef 
} from '@angular/core'; 

import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; 
import * as Cropper from 'cropperjs'; 
import { Photo } from '../entities/photo'; 

@Component({ 
    selector: 'image-edit', 
    templateUrl: 'image-edit.component.html', 
    styleUrls: [ 
     'image-edit.component.scss', 
     '../../../node_modules/cropperjs/dist/cropper.min.css' 
], 
encapsulation: ViewEncapsulation.None, 
providers: [ 
    { 
     provide: NG_VALUE_ACCESSOR, 
     useExisting: forwardRef(() => ImageEditComponent), 
     multi: true 
    } 
    ] 
}) 

export class ImageEditComponent implements OnInit, ControlValueAccessor { 

    get value() { 
     return this.cropperImage.nativeElement.src; 
    } 

    set value(v: string) { 
     this.cropperImage.nativeElement.src = v; 
    } 

    public onTouch:() => void; 
    public onChange: (_: any) => void; 

    @ViewChild('cropperImage') 
    private cropperImage: ElementRef; 

    private isDisabled: boolean; 

    // cropper.js 
    private cropper: Cropper; 
    private cropperOptions: Cropper.CropperOptions = {}; 

    public ngOnInit(): void { 

     // init cropper.js 
    } 

    public writeValue(obj: any): void { 

     if (obj) { 
      this.value = obj; 
      this.initializeCropperOrReplaceImage(); 
     } 
    } 

    public registerOnChange(fn: any): void { 
     this.onChange = fn; 
    } 

    public registerOnTouched(fn: any): void { 
     this.onTouch = fn; 
    } 

    public setDisabledState(isDisabled: boolean): void { 
     this.isDisabled = isDisabled; 
    } 

    private initializeCropperOrReplaceImage(): void { 

     if (!this.isCropperInitialized) { 
      this.cropper = new Cropper(this.cropperImage.nativeElement, this.cropperOptions); 
      this.isCropperInitialized = true; 
     } 
     else { 
      this.cropper.replace(this.cropperImage.nativeElement.src); 
     } 

     URL.revokeObjectURL(this.cropperImage.nativeElement.src); 
    } 
} 

(私はいくつかのcropper.jsに読みやすくするための固有のコードを削除)コードです、ここで残念ながら私のコントロールが汚れていたり、触れたことはありませんテンプレート

<image-edit [hidden]="!photo.data" #photoData="ngModel" name="photoData" [(ngModel)]="photo.data" validateMinImageDimensions minWidth="300" minHeight="400"> 
</image-edit> 

です。 私はAbstractFormを拡張しようとしましたが、自分自身を汚いと設定しましたが、それは動作しませんでした。それは不潔で手つかずのままです。

私が間違っていることは何ですか?

EDIT

私はそれは良い解決策ではありません(そこを参照)n00dl3答えとコメント@によるのでonTouchwriteValueonChangeへの呼び出しを削除しました。あなたの入力は触れどちらも汚れとしてマークすることはできませんので

+0

があなたのコンポーネントのテンプレートを追加してください。 – n00dl3

答えて

1

あなたは、あなたのコンポーネントでthis.onTouch()を呼び出すことはありません....

+0

それは、 'writeValue'で' onTouch() 'と' onChange(obj) 'を呼び出す必要がありました。 コード – Arikael

+1

で質問を更新しましたが、 'writeValue'でこれらを使用するのは意味がありません。モデルがビューを更新するときに' writeValue'が呼び出されるので、画像を切り取ったときにこれらのコールバックを呼び出す必要があります。 – n00dl3

+0

追加入力をいただき、ありがとうございます。 – Arikael

関連する問題