Skip to content

Commit

Permalink
feat(module: slider): slider add ngModel (#202)
Browse files Browse the repository at this point in the history
  • Loading branch information
sWhite01111 authored and fisherspy committed Dec 27, 2018
1 parent 395efcb commit 3db39ae
Show file tree
Hide file tree
Showing 18 changed files with 115 additions and 21 deletions.
Empty file modified components/slider/demo/basic.md
100644 → 100755
Empty file.
13 changes: 13 additions & 0 deletions components/slider/demo/basic.ts
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ import { Component, OnInit } from '@angular/core';
template: `
<div class="am-demo-page">
<div style="padding: 15px;font-size: 16px;">步骤条</div>
<div class="am-demo-bd am-wingblank am-wingblank-lg">
<div>
<div class="sub-title">Small size ngModel</div>
</div>
<div>
<Slider [ngModel]="value"
[min]=-10
[max]=100
(ngModelChange)="change($event)"
(onAfterChange)="afterChange($event)"
></Slider>
</div>
</div>
<div class="am-demo-bd am-wingblank am-wingblank-lg">
<div>
<div class="sub-title">Small size</div>
Expand Down
2 changes: 2 additions & 0 deletions components/slider/doc/index.en-US.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ A Slider component for selecting particular value in range, eg: controls the dis

Properties | Descrition | Type | Default
-----------|------------|------|--------
| ngModel| Number | | The value of slider, double binding. |
| ngModelChange | Function | Noop | Callback function that is called when the user changes the slider's value. |
| min | Number | 0 | The minimum value the slider can slide to. |
| max | Number | 100 | The maximum value the slider can slide to. |
| step | Number or null | 1 | The granularity the slider can step through values. Must greater than 0, and be divided by (max - min) . When `marks` no null, `step` can be `null`. |
Expand Down
2 changes: 2 additions & 0 deletions components/slider/doc/index.zh-CN.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ subtitle: 滑动输入条

属性 | 类型 | 默认值 | 说明
----|-----|------|------
| ngModel| Number | | 设置当前取值,可双向绑定。 |
| ngModelChange | Function | Noop | 当 Slider 的值发生改变时,会触发 ngModelChange 事件,并把改变后的值作为参数传入。 |
| min | Number | 0 | 最小值 |
| max | Number | 100 | 最大值 |
| step | Number or null | 1 | 步长,取值必须大于 0,并且可被 (max - min) 整除。当 `marks` 不为空对象时,可以设置 `step``null`,此时 Slider 的可选值仅有 marks 标出来的部分。 |
Expand Down
Empty file modified components/slider/slider-handle/slider-handle.component.html
100644 → 100755
Empty file.
7 changes: 3 additions & 4 deletions components/slider/slider-handle/slider-handle.component.ts
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export class SliderHandle implements OnInit, OnDestroy {
document.addEventListener('mouseup', this.mouseUp, false);
this.pauseEvent(event);
}
};
}

mouseMove = event => {
if (!this._disabled && this._isDraging) {
Expand All @@ -148,7 +148,7 @@ export class SliderHandle implements OnInit, OnDestroy {
this.onChange.emit(this._value);
}
}
};
}

mouseUp = event => {
if (!this._disabled && this._isDraging) {
Expand All @@ -159,7 +159,7 @@ export class SliderHandle implements OnInit, OnDestroy {
this.left = this.calcOffset(this._value);
this.onAfterChange.emit(this._value);
}
};
}

calcValueByPos(pos) {
const offset = pos - this._sliderStart;
Expand Down Expand Up @@ -240,7 +240,6 @@ export class SliderHandle implements OnInit, OnDestroy {
this.left = this.calcOffset(this._value);
this._minBound = this._minBound === undefined ? this._min : this._minBound;
this._maxBound = this._maxBound === undefined ? this._max : this._maxBound;
this.onAfterChange.emit(this._value);
}

ngOnDestroy() {
Expand Down
Empty file modified components/slider/slider-marks/slider-marks.component.html
100644 → 100755
Empty file.
Empty file modified components/slider/slider-marks/slider-marks.component.ts
100644 → 100755
Empty file.
Empty file modified components/slider/slider-steps/slider-steps.component.html
100644 → 100755
Empty file.
Empty file modified components/slider/slider-steps/slider-steps.component.ts
100644 → 100755
Empty file.
Empty file modified components/slider/slider-track/slider-track.component.html
100644 → 100755
Empty file.
Empty file modified components/slider/slider-track/slider-track.component.ts
100644 → 100755
Empty file.
Empty file modified components/slider/slider.component.html
100644 → 100755
Empty file.
39 changes: 37 additions & 2 deletions components/slider/slider.component.spec.ts
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { OnInit, Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SliderModule } from './slider.module';
Expand All @@ -8,6 +9,7 @@ describe('SliderComponent', () => {
let component: TestSliderComponent;
let fixture: ComponentFixture<TestSliderComponent>;
let sliderEle;
let sliderEles;
let amSlider;
let sliderHandler;
let sliderSteps;
Expand All @@ -16,14 +18,15 @@ describe('SliderComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestSliderComponent],
imports: [SliderModule]
imports: [SliderModule, FormsModule]
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(TestSliderComponent);
component = fixture.componentInstance;
sliderEle = fixture.debugElement.query(By.css('Slider'));
sliderEles = fixture.debugElement.queryAll(By.css('Slider'));
amSlider = sliderEle.nativeElement.querySelector('.am-slider');
sliderHandler = sliderEle.nativeElement.querySelector('.am-slider-handle');
sliderSteps = sliderEle.nativeElement.querySelector('.am-slider-step');
Expand Down Expand Up @@ -105,6 +108,24 @@ describe('SliderComponent', () => {
expect(component.change).toHaveBeenCalled();
expect(component.afterChange).toHaveBeenCalled();
});
it('should ngModel work', () => {
amSlider = sliderEles[1].nativeElement.querySelector('.am-slider');
sliderHandler = sliderEles[1].nativeElement.querySelector('.am-slider-handle');
sliderSteps = sliderEles[1].nativeElement.querySelector('.am-slider-step');
const sliderCoords = amSlider.getBoundingClientRect();
const sliderLength = sliderCoords.width;
const sliderStart = sliderCoords.left;
const offset = Math.round(((230 - sliderStart) / sliderLength) * 100);

const sliderHandlerNode = sliderEles[1].nativeElement.querySelector('sliderhandle');
dispatchTouchEvent(sliderHandlerNode, 'touchstart');
fixture.detectChanges();
dispatchTouchEvent(sliderHandlerNode, 'touchmove', 230);
fixture.detectChanges();
dispatchTouchEvent(sliderHandlerNode, 'touchend');
expect(sliderHandler.getAttribute('style')).toContain('left: ' + offset + '%');
expect(component.modelChange).toHaveBeenCalled();
});
});

@Component({
Expand All @@ -125,6 +146,20 @@ describe('SliderComponent', () => {
(onChange)="change($event)"
(onAfterChange)="afterChange($event)"
></Slider>
<Slider [min]= "min"
[max]="max"
[dots]="dots"
[step]="step"
[marks]="marks"
[(ngModel)]="value"
[disabled]="disabled"
[included]="included"
[railStyle]="railStyle"
[trackStyle]="trackStyle"
[handleStyle]="handleStyle"
(ngModelChange)="modelChange($event)"
(onAfterChange)="afterChange($event)"
></Slider>
`
})
export class TestSliderComponent implements OnInit {
Expand All @@ -143,7 +178,7 @@ export class TestSliderComponent implements OnInit {

afterChange = jasmine.createSpy('afterChange callback');
change = jasmine.createSpy('change callback');

modelChange = jasmine.createSpy('ngModelChange callback');
constructor() {}

ngOnInit() {
Expand Down
73 changes: 58 additions & 15 deletions components/slider/slider.component.ts
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ import {
EventEmitter,
ElementRef,
ViewEncapsulation,
HostBinding
HostBinding,
forwardRef
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
selector: 'Slider , nzm-slider',
templateUrl: './slider.component.html',
encapsulation: ViewEncapsulation.None
encapsulation: ViewEncapsulation.None,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Slider),
multi: true
}
]
})
export class Slider implements OnInit {
export class Slider implements OnInit, ControlValueAccessor {
prefixCls = 'am-slider';
sliderLength: number;
sliderStart: number;
Expand All @@ -25,8 +34,8 @@ export class Slider implements OnInit {
private _min: number = 0;
private _max: number = 100;
private _step: number = 1;
private _value: number = 10;
private _defaultValue: number;
private _value: number;
private _defaultValue: number = 0;
private _disabled: boolean = false;
private _marks: object = {};
private _dots: boolean = false;
Expand Down Expand Up @@ -61,13 +70,12 @@ export class Slider implements OnInit {
return this._value;
}
set value(value: number) {
this._value = value;
this.valueRange();
this.setValue(value);
}
@Input()
set defaultValue(value) {
this._defaultValue = value;
this._value = this._defaultValue;
this.setValue(value);
}
@Input()
get disabled(): boolean {
Expand Down Expand Up @@ -119,14 +127,18 @@ export class Slider implements OnInit {
set railStyle(value: object) {
this._railStyle = value;
}
@Output()
onChange = new EventEmitter<any>();

@Output()
onAfterChange = new EventEmitter<any>();
@Output()
onChange = new EventEmitter<any>();

@HostBinding('class.am-slider-wrapper')
amSliderWrapper: boolean = true;

private _ngModelOnChange: (value: number) => void = () => {};
private _ngModelOnTouched: (value: number) => void = () => {};

constructor(private _elf: ElementRef) {}

setCls() {
Expand All @@ -137,17 +149,16 @@ export class Slider implements OnInit {

handleChange(e) {
setTimeout(() => {
this.offset = 0;
this.length = ((e - this._min) * 100) / (this._max - this._min);
this.setTrack(e);
this._value = e;
}, 10);
this.onChange.emit(e);
this._ngModelOnChange(e);
}

handleAfterChange(e) {
setTimeout(() => {
this.offset = 0;
this.length = ((e - this._min) * 100) / (this._max - this._min);
this.setTrack(e);
this._value = e;
}, 10);
this.onAfterChange.emit(e);
Expand All @@ -164,9 +175,41 @@ export class Slider implements OnInit {

ngOnInit() {
this.setCls();
this.valueRange();
this.setValue(this._value);
const sliderCoords = this._elf.nativeElement.getElementsByClassName('am-slider')[0].getBoundingClientRect();
this.sliderLength = sliderCoords.width;
this.sliderStart = sliderCoords.left;
}

writeValue(value: number): void {
this.setValue(value, true);
}

setValue(value: number, isWriteValue = false) {
if (value === 0 || value) {
this._value = value;
} else {
this._value = this._defaultValue;
}
this.valueRange();
this.setTrack(this._value);
if (isWriteValue) {
this._ngModelOnChange(this._value);
} else {
this.onAfterChange.emit(this._value);
}
}

setTrack(e) {
this.offset = 0;
this.length = ((e - this._min) * 100) / (this._max - this._min);
}

registerOnChange(fn: (value: number) => void): void {
this._ngModelOnChange = fn;
}

registerOnTouched(fn: (value: number) => void): void {
this._ngModelOnTouched = fn;
}
}
Empty file modified components/slider/slider.module.ts
100644 → 100755
Empty file.
Empty file modified components/slider/style/addon.less
100644 → 100755
Empty file.
Empty file modified components/slider/style/index.less
100644 → 100755
Empty file.

0 comments on commit 3db39ae

Please sign in to comment.