2017-03-08 66 views
0

我有一個簡單的組件,它包括我在我的形式是這樣的:NgModel

<app-slider [min]="field.min" [max]="field.max" [value]="field.min"></app-slider> 

組件如下:

HTML:

<input #mySlider 
     class="slider" 
     type="text" 
     name="slider" 
     data-provide="slider" 
     data-slider-min="1" 
     data-slider-max="3" 
     [attr.data-slider-min]="min" 
     [attr.data-slider-max]="max" 
     data-slider-step="1" 
     [attr.data-slider-value]="value" 
     data-slider-tooltip="show"/> 

TS:

import {Component, ViewChild, Input} from '@angular/core'; 

declare var $ : any; 

@Component({ 
    selector: 'app-slider', 
    templateUrl: './slider.component.html', 
    styleUrls: ['./slider.component.css'] 
}) 
export class SliderComponent{ 
    @ViewChild('mySlider') slider: any; // can be ElementRef; 
    @Input() min: number; 
    @Input() max: number; 
    @Input() value: number; 

    constructor() { } 

    ngAfterViewInit() { 
     // slider is available 
     $(this.slider.nativeElement).slider(); 
     let value = $(this.slider.nativeElement).attr("data-slider-value"); 
     $(this.slider.nativeElement).slider('setValue', value); 
    } 
} 

我想在我的組件上添加NgModel,以便我可以獲取並更改其值:

<app-slider [min]="field.min" [max]="field.max" [value]="field.min" [(ngModel)]="currentValue"></app-slider> 

我該如何做到這一點?

回答

3

試試這個:

<app-slider [min]="field.min" [max]="field.max" [(value)]="currentValue"></app-slider> 

變化currentValue值使用changeCurrentValue

import {Component, ViewChild, Input, Output, EventEmitter} from '@angular/core'; 

declare var $ : any; 

@Component({ 
    selector: 'app-slider', 
    templateUrl: './slider.component.html', 
    styleUrls: ['./slider.component.css'] 
}) 
export class SliderComponent{ 
    @ViewChild('mySlider') slider: any; // can be ElementRef; 
    @Input() min: number; 
    @Input() max: number; 
    @Input() value: number; 
    @Output() valueChange = new EventEmitter(); 
    constructor() { } 

    ngAfterViewInit() { 
     let self = this; 
     // slider is available 
     $(this.slider.nativeElement).slider(); 
     let value = $(this.slider.nativeElement).attr("data-slider-value"); 
     $(this.slider.nativeElement).slider('setValue', value); 

     $(this.slider.nativeElement).slider().on('change', function(event) { 
      self.value = event.value.newValue; self.valueChange.emit(self.value); }); 
      } 

    changeCurrentValue(){ 
     this.value= //some value; 
     this.valueChange.emit(this.value); 
    } 
} 
+0

我剛剛寫了與ssougnez答案几乎完全相同的代碼,但我使用jquery方法從滑塊獲取更新 $(this.slider.nativeElement).slider()。on('change',function (事件){ \t THIS.VALUE = event.value.newValue; \t this.valueChange.emit(THIS.VALUE); });' 問題是,我得到一個錯誤的值發生變化時。 EventEmitter變量未定義:'不能讀取'undefined'屬性'emit'。我知道這與雙向數據綁定無關。但是,你認爲這是由於ngAfterViewInit方法嗎? – Servietsky

+0

@Servietsky看到更新,不要在'on'函數中使用'this' –

+1

您也可以使用胖箭頭操作符來避免與此不匹配,對不對? – ssougnez

3

前言:它看起來像你使用某事像jQuery UI的滑塊,但有點不同。在我不得不假設的地方,我使用了它的api。

基本上你想要做的事情是通過執行ControlValueAccessor來實現的,以便將組件識別爲ng,並將其作爲表單控件或換句話說自定義窗體控件。不知道是否語法是最新與最新NG的方法,但礦用如下所示:

import { Component, ViewChild, Input, EventEmitter, forwardRef } from '@angular/core'; 
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; 

declare var $: any; 

export const SLIDER_VALUE_ACCESSOR: any = { 
    provide: NG_VALUE_ACCESSOR, 
    useExisting: forwardRef(() => SliderComponent), 
    multi: true 
}; 

@Component({ 
    selector: 'app-slider', 
    templateUrl: './slider.component.html', 
    styleUrls: ['./slider.component.css'], 
    providers: [ 
     SLIDER_VALUE_ACCESSOR 
    ] 
}) 
export class SliderComponent implements ControlValueAccessor { 
    @ViewChild('mySlider') slider: any; // can be ElementRef; 
    @Input() min: number; 
    @Input() max: number; 

    propagateChange = (_: any) => { }; 
    propagateTouched =() => { }; 

    constructor() { } 

    ngAfterViewInit() { 
     // slider is available 
     $(this.slider.nativeElement).slider(); 
    } 

    onChange() { 
     this.propagateChange($(this.slider.nativeElement).attr("data-slider-value");); 
    } 

    /** 
    * Write a new value to the element. 
    */ 
    writeValue(value: any): void { 
     $(this.slider.nativeElement).slider('setValue', value); 
    } 

    /** 
    * Set the function to be called when the control receives a change event. 
    */ 
    registerOnChange(fn: any): void { 
     this.propagateChange = fn; 
    } 

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

    /** 
    * This function is called when the control status changes to or from "DISABLED". 
    * Depending on the value, it will enable or disable the appropriate DOM element. 
    * 
    * @param isDisabled 
    */ 
    setDisabledState?(isDisabled: boolean): void { 
     // it would look like this if jQuery UI slider was used 
     $(this.slider.nativeElement).slider(isDisabled ? "disable" : "enable"); 
    } 
} 

模板,如:

<input #mySlider 
    class="slider" 
    type="text" 
    name="slider" 
    data-provide="slider" 
    data-slider-min="1" 
    data-slider-max="3" 
    [attr.data-slider-min]="min" 
    [attr.data-slider-max]="max" 
    data-slider-step="1" 
    data-slider-tooltip="show" 
    (change)="onChange" /> <!-- change event as in jQuery UI slider --> 

和用法:

<app-slider [min]="field.min" [max]="field.max" [(ngModel)]="currentValue"></app-slider>

並且currentValue必須使用min值進行初始化,才能正常工作,因爲它似乎適用於示例。