diff --git a/components/locale-provider/demo/basic.ts b/components/locale-provider/demo/basic.ts
index 25bdb7c6..8eb5f03d 100644
--- a/components/locale-provider/demo/basic.ts
+++ b/components/locale-provider/demo/basic.ts
@@ -11,9 +11,9 @@ import { en_US, ru_RU, zh_CN, sv_SE, da_DK } from 'ng-zorro-antd-mobile';
[arrow]="'horizontal'"
[cols]="1"
[extra]="locale"
- [value]="[locale]"
+ [(ngModel)]="lang"
[data]="languages"
- (onOk)="onChange($event)"
+ (ngModelChange)="onChange($event)"
>
Choose language
@@ -47,6 +47,13 @@ import { en_US, ru_RU, zh_CN, sv_SE, da_DK } from 'ng-zorro-antd-mobile';
providers: []
})
export class DemoLocaleProviderBasicComponent {
+ lang = [
+ {
+ value: '中文',
+ label: '中文',
+ language: zh_CN
+ }
+ ];
locale = '中文';
data = [
{
@@ -121,9 +128,9 @@ export class DemoLocaleProviderBasicComponent {
constructor(private _localeProviderService: LocaleProviderService) {}
- onChange = item => {
+ onChange = (item) => {
this.locale = item[0].value;
const currentLocale = this.languages.find(i => i.value === this.locale).language;
this._localeProviderService.setLocale(currentLocale);
- };
+ }
}
diff --git a/components/picker/demo/basic.ts b/components/picker/demo/basic.ts
index 2ae61c98..c9c4b58f 100644
--- a/components/picker/demo/basic.ts
+++ b/components/picker/demo/basic.ts
@@ -11,8 +11,8 @@ import { Picker } from 'ng-zorro-antd-mobile';
[arrow]="'horizontal'"
[mask]=true
[title]="'Areas'"
- [value]="value1"
- (onOk)="onOk1($event)"
+ [(ngModel)]="value1"
+ (ngModelChange)="onOk1($event)"
>
Multiple & cascader
@@ -22,8 +22,8 @@ import { Picker } from 'ng-zorro-antd-mobile';
[cascade]="false"
[data]="seasons"
[title]="'选择季节'"
- [value]="value2"
- (onOk)="onOk2($event)"
+ [(ngModel)]="value2"
+ (ngModelChange)="onOk2($event)"
>
Multiple
@@ -31,17 +31,17 @@ import { Picker } from 'ng-zorro-antd-mobile';
[extra]="name3"
[arrow]="'horizontal'"
[data]="singleArea"
- [value]="value3"
- (onOk)="onOk3($event)"
+ [(ngModel)]="value3"
+ (ngModelChange)="onOk3($event)"
>
Single
Multiple & async
@@ -113,22 +113,18 @@ export class DemoPickerBasicComponent {
onOk1(result) {
this.name1 = this.getResult(result);
- this.value1 = this.getValue(result);
}
onOk2(result) {
this.name2 = this.getResult(result);
- this.value2 = this.getValue(result);
}
onOk3(result) {
this.name3 = this.getResult(result);
- this.value3 = this.getValue(result);
}
onOk4(result) {
this.name4 = this.getResult(result);
- this.value4 = this.getValue(result);
}
onPickerChange(result) {
diff --git a/components/picker/doc/index.en-US.md b/components/picker/doc/index.en-US.md
index 81906716..92db153c 100644
--- a/components/picker/doc/index.en-US.md
+++ b/components/picker/doc/index.en-US.md
@@ -14,14 +14,14 @@ Choose from a set of data, e.g. Country choice.
Properties | Descrition | Type | Default
-----------|------------|------|--------
+| ngModel | Current selected value, the format is `[value1, value2, value3]`, corresponds to the level value of the data source,double binding | Array | - |
| data | data source | `Array<{value, label, children: Array}>` | - |
-| value | the value, the format is `[value1, value2, value3]`, corresponds to the level value of the data source | Array | - |
| cols | col numbers | Number | `3` |
| onChange | selected callback function | (val): void | - |
| onPickerChange | trigger on each column of selected data is changed | (val): void | - |
| okText | ok text | String | `确定` |
| dismissText | dismiss text | String | `取消` |
-| onOk | handler called when click ok | (val): void | - |
+| ngModelChange | handler called when click ok | EventEmitter | - |
| onDismiss | handler called when click cancel | (): void | - |
| title | title | String | - |
| disabled | set disabled | Boolean | false |
diff --git a/components/picker/doc/index.zh-CN.md b/components/picker/doc/index.zh-CN.md
index 9c2d172d..34cc8ac3 100644
--- a/components/picker/doc/index.zh-CN.md
+++ b/components/picker/doc/index.zh-CN.md
@@ -15,14 +15,14 @@ subtitle: 选择器
属性 | 说明 | 类型 | 默认值
----|-----|------|------
+| ngModel | 当前值, 格式是`[value1, value2, value3]`, 对应数据源的相应级层value, 可双向绑定 | Array | - |
| data | 数据源 | `Array<{value, label, children: Array}>` | - |
-| value | 值, 格式是`[value1, value2, value3]`, 对应数据源的相应级层value | Array | - |
| cols | 列数 | Number | `3` |
| onChange | 选中后的回调 | (val): void | - |
| onPickerChange | 每列数据选择变化后的回调函数 | (val): void | - |
| okText | 选中的文案 | String | `确定` |
| dismissText | 取消选中的文案 | String | `取消` |
-| onOk | 点击选中时执行的回调 | (val): void | 无 |
+| ngModelChange | 点击选中时执行的回调 | EventEmitter | - |
| onDismiss | 点击取消时执行的回调 | (): void | 无 |
| title | 大标题 | String | - |
| disabled | 是否不可用 | Boolean | false |
diff --git a/components/picker/picker-options.provider.ts b/components/picker/picker-options.provider.ts
index 70b472f8..1dfa314f 100644
--- a/components/picker/picker-options.provider.ts
+++ b/components/picker/picker-options.provider.ts
@@ -22,13 +22,13 @@ export class PickerOptions implements PickerOptionsInterface {
disabled?: boolean = false;
cascade?: boolean = true;
appendToBody?: boolean = false;
- onOk?: EventEmitter = new EventEmitter();
onDismiss?: EventEmitter = new EventEmitter();
onPickerChange?: EventEmitter = new EventEmitter();
indicatorStyle?: object = {};
hidePicker?: () => void;
confirm?: (result) => void;
cancel?: () => void;
+ updateNgModel?: (value: any[]) => void;
}
export type PickerCallBack = (result?: any) => PromiseLike | void;
diff --git a/components/picker/picker.component.spec.ts b/components/picker/picker.component.spec.ts
index 2166f137..e3d607dd 100644
--- a/components/picker/picker.component.spec.ts
+++ b/components/picker/picker.component.spec.ts
@@ -1,4 +1,5 @@
import { Component } from '@angular/core';
+import { FormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { async, ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { ListModule, PickerModule, PickerComponent } from '../..';
@@ -9,6 +10,7 @@ import { LocaleProviderService, LocaleProviderModule } from '../..';
import { Button } from '../button/button.component';
import { ButtonModule } from '../button/button.module';
import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
+
describe('PickerComponent', () => {
let component: TestPickerBasicComponent;
let fixture: ComponentFixture;
@@ -20,7 +22,7 @@ describe('PickerComponent', () => {
TestBed.configureTestingModule({
declarations: [TestPickerBasicComponent],
providers: [PickerOptions, LocaleProviderService, Picker, Overlay],
- imports: [ListModule, PickerModule, LocaleProviderModule, ButtonModule]
+ imports: [ListModule, PickerModule, LocaleProviderModule, ButtonModule, FormsModule]
}).compileComponents();
TestBed.overrideModule(PickerModule, {
set: { entryComponents: [PickerComponent] }
@@ -84,15 +86,14 @@ describe('PickerComponent', () => {
pickerEle.querySelector('.am-picker-popup-header-right').click();
});
- it('onOk work', () => {
+ it('should ngModel work', () => {
const list = lists[0].nativeElement;
list.click();
fixture.detectChanges();
pickerEle = document.querySelector('picker');
- component.onOk1 = jasmine.createSpy('onOk1 is callback');
pickerEle.querySelector('.am-picker-popup-header-right').click();
fixture.detectChanges();
- expect(component.onOk1).toHaveBeenCalledTimes(1);
+ expect(component.modelChange).toHaveBeenCalledTimes(1);
});
it ('should touch event work', () => {
@@ -134,10 +135,10 @@ describe('PickerComponent', () => {
[mask]="mask"
[extra]="name1"
[title]="title"
- [value]="value1"
+ [(ngModel)]="value1"
[data]="singleArea"
[arrow]="'horizontal'"
- (onOk)="onOk1($event)"
+ (ngModelChange)="modelChange($event)"
>
Multiple & cascader
@@ -172,19 +173,10 @@ export class TestPickerBasicComponent {
value1 = ['宣武区'];
title = 'result';
mask = true;
+ modelChange = jasmine.createSpy('ngModel change callback');
- constructor (private _picker: Picker ) {
-
- }
-
- onOk1(result) {
- this.name1 = this.getResult(result);
- this.value1 = this.getValue(result);
- }
+ constructor (private _picker: Picker) {
- onPickerChange(result) {
- this.name1 = this.getResult(result);
- this.value1 = this.getValue(result);
}
getResult(result) {
diff --git a/components/picker/picker.component.ts b/components/picker/picker.component.ts
index 765168c8..eb634782 100644
--- a/components/picker/picker.component.ts
+++ b/components/picker/picker.component.ts
@@ -227,7 +227,7 @@ export class PickerComponent implements OnInit, AfterViewInit, OnDestroy {
}
ok() {
- this.options.onOk.emit(this.combineReslut());
+ this.options.updateNgModel(this.combineReslut());
if (this.options.confirm) {
this.options.confirm(this.combineReslut());
}
diff --git a/components/picker/picker.directive.ts b/components/picker/picker.directive.ts
index f041b6f6..ac79ffe0 100644
--- a/components/picker/picker.directive.ts
+++ b/components/picker/picker.directive.ts
@@ -14,23 +14,31 @@ import {
ComponentFactoryResolver,
Renderer2,
ComponentFactory,
- SimpleChanges
+ SimpleChanges,
+ forwardRef
} from '@angular/core';
import { PickerComponent } from './picker.component';
import { PickerOptions } from './picker-options.provider';
+import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Directive({
- selector: '[Picker], [nzm-picker]'
+ selector: '[Picker], [nzm-picker]',
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => PickerDirective),
+ multi: true
+ }
+ ]
})
-export class PickerDirective implements OnDestroy, OnChanges, OnInit {
+export class PickerDirective implements OnDestroy, OnChanges, OnInit, ControlValueAccessor {
picker: ComponentRef;
+ value: Array;
private _eventListeners: Array<() => void> = [];
@Input()
data: Array;
@Input()
- value: Array;
- @Input()
cols: Number;
@Input()
mask: boolean;
@@ -55,10 +63,11 @@ export class PickerDirective implements OnDestroy, OnChanges, OnInit {
@Output()
onPickerChange: EventEmitter = new EventEmitter();
@Output()
- onOk: EventEmitter = new EventEmitter();
- @Output()
onDismiss: EventEmitter = new EventEmitter();
+ onChange: (value: any[]) => void = () => null;
+ onTouched: () => void = () => null;
+
@HostListener('click')
togglePicker(): void {
if (!this.picker) {
@@ -117,6 +126,9 @@ export class PickerDirective implements OnDestroy, OnChanges, OnInit {
Object.assign(options, this._defaultOptions, {
hidePicker: (event): void => {
this.hidePicker();
+ },
+ updateNgModel: (value: any[]): void => {
+ this.onChange(value);
}
});
@@ -132,7 +144,6 @@ export class PickerDirective implements OnDestroy, OnChanges, OnInit {
'cascade',
'appendToBody',
'indicatorStyle',
- 'onOk',
'onPickerChange'
];
optionalParams.forEach(param => {
@@ -168,4 +179,20 @@ export class PickerDirective implements OnDestroy, OnChanges, OnInit {
this._eventListeners = [];
}
}
+
+ writeValue(value: any[]): void {
+ this.value = Array.isArray(value) ? value : [];
+ }
+
+ registerOnChange(fn: (value: any[]) => void): void {
+ this.onChange = fn;
+ }
+
+ registerOnTouched(fn: () => void): void {
+ this.onTouched = fn;
+ }
+
+ setDisabledState(isDisabled: boolean): void {
+ this.disabled = isDisabled;
+ }
}