2017-04-05 1 views
1

Ich erstellte ein benutzerdefiniertes Steuerelement, dem ich den Wert programmgesteuert da es ein Bild-Editor basierend auf cropper.js und der Benutzer "uploadet" ein Bild über einen normalen Dateieingang und ich Verwenden Sie dann die Datei-API, um das Bild meinem benutzerdefinierten Steuerelement zuzuweisen.Angular 2, benutzerdefiniertes Steuerelement ist nie als schmutzig markiert

hier der Code ist (Ich entfernte einige cropper.js spezifischen Code zur besseren Lesbarkeit)

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); 
    } 
} 

hier ist die Vorlage

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

Leider nie schmutzig meiner Kontrolle ist oder berührt. Ich habe versucht, AbstractForm zu erweitern und dreckig zu setzen, aber es hat nicht funktioniert. Es bleibt untrüglich und unberührt.

Irgendwelche Ideen, was ich falsch mache?

EDIT

entfernte ich den Anruf zu onTouch und onChange in writeValue weil zu @ n00dl3 Antwort und Kommentar nach (siehe dort) es keine gute Lösung ist.

+0

bitte Ihre Komponente der Vorlage hinzufügen. – n00dl3

Antwort

1

Sie nie this.onTouch() in Ihrer Komponente aufrufen, so dass Ihre Eingabe nicht so berührt weder schmutzig markiert werden können ....

+0

das war es, ich musste 'onTouch()' und 'onChange (obj)' in 'writeValue' aufrufen. Ich habe die Frage mit dem Code – Arikael

+1

aktualisiert, es macht keinen Sinn, diese in 'writeValue' zu ​​verwenden,' writeValue' wird aufgerufen, wenn das Modell die Ansicht aktualisiert. Sie sollten diese Callbacks aufrufen, wenn Sie das Bild zugeschnitten haben. – n00dl3

+0

danke für die zusätzliche Eingabe, ich werde es mir ansehen – Arikael

Verwandte Themen