fix(forms): support both value and ng-value
This commit is contained in:
parent
9be04f8d38
commit
8db97b0b7a
@ -15,6 +15,7 @@ import {
|
|||||||
StringWrapper,
|
StringWrapper,
|
||||||
isPrimitive,
|
isPrimitive,
|
||||||
isPresent,
|
isPresent,
|
||||||
|
isBlank,
|
||||||
looseIdentical
|
looseIdentical
|
||||||
} from 'angular2/src/facade/lang';
|
} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ const SELECT_VALUE_ACCESSOR = CONST_EXPR(new Provider(
|
|||||||
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => SelectControlValueAccessor), multi: true}));
|
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => SelectControlValueAccessor), multi: true}));
|
||||||
|
|
||||||
function _buildValueString(id: string, value: any): string {
|
function _buildValueString(id: string, value: any): string {
|
||||||
|
if (isBlank(id)) return `${value}`;
|
||||||
if (!isPrimitive(value)) value = "Object";
|
if (!isPrimitive(value)) value = "Object";
|
||||||
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
||||||
}
|
}
|
||||||
@ -70,7 +72,10 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getOptionValue(valueString: string): any { return this._optionMap.get(_extractId(valueString)); }
|
_getOptionValue(valueString: string): any {
|
||||||
|
let value = this._optionMap.get(_extractId(valueString));
|
||||||
|
return isPresent(value) ? value : valueString;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,14 +98,21 @@ export class NgSelectOption implements OnDestroy {
|
|||||||
if (isPresent(this._select)) this.id = this._select._registerOption();
|
if (isPresent(this._select)) this.id = this._select._registerOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input()
|
@Input('ng-value')
|
||||||
set value(value: any) {
|
set ngValue(value: any) {
|
||||||
if (this._select == null) return;
|
if (this._select == null) return;
|
||||||
this._select._optionMap.set(this.id, value);
|
this._select._optionMap.set(this.id, value);
|
||||||
this._setElementValue(_buildValueString(this.id, value));
|
this._setElementValue(_buildValueString(this.id, value));
|
||||||
this._select.writeValue(this._select.value);
|
this._select.writeValue(this._select.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Input('value')
|
||||||
|
set value(value: any) {
|
||||||
|
if (this._select == null) return;
|
||||||
|
this._setElementValue(value);
|
||||||
|
this._select.writeValue(this._select.value);
|
||||||
|
}
|
||||||
|
|
||||||
_setElementValue(value: string): void {
|
_setElementValue(value: string): void {
|
||||||
this._renderer.setElementProperty(this._element.nativeElement, 'value', value);
|
this._renderer.setElementProperty(this._element.nativeElement, 'value', value);
|
||||||
}
|
}
|
||||||
|
@ -396,10 +396,11 @@ export function main() {
|
|||||||
var select = fixture.debugElement.query(By.css("select"));
|
var select = fixture.debugElement.query(By.css("select"));
|
||||||
var sfOption = fixture.debugElement.query(By.css("option"));
|
var sfOption = fixture.debugElement.query(By.css("option"));
|
||||||
|
|
||||||
expect(select.nativeElement.value).toEqual("0: SF");
|
|
||||||
|
expect(select.nativeElement.value).toEqual("SF");
|
||||||
expect(sfOption.nativeElement.selected).toBe(true);
|
expect(sfOption.nativeElement.selected).toBe(true);
|
||||||
|
|
||||||
select.nativeElement.value = "1: NYC";
|
select.nativeElement.value = "NYC";
|
||||||
dispatchEvent(select.nativeElement, "input");
|
dispatchEvent(select.nativeElement, "input");
|
||||||
|
|
||||||
expect(fixture.debugElement.componentInstance.form.value).toEqual({"city": 'NYC'});
|
expect(fixture.debugElement.componentInstance.form.value).toEqual({"city": 'NYC'});
|
||||||
@ -423,12 +424,13 @@ export function main() {
|
|||||||
|
|
||||||
fixture.debugElement.componentInstance.form =
|
fixture.debugElement.componentInstance.form =
|
||||||
new ControlGroup({"city": new Control("NYC")});
|
new ControlGroup({"city": new Control("NYC")});
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.data = ['SF', 'NYC'];
|
fixture.debugElement.componentInstance.data = ['SF', 'NYC'];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
var select = fixture.debugElement.query(By.css("select"));
|
var select = fixture.debugElement.query(By.css("select"));
|
||||||
expect(select.nativeElement.value).toEqual("1: NYC");
|
expect(select.nativeElement.value).toEqual("NYC");
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it("with option values that are objects",
|
it("with option values that are objects",
|
||||||
@ -436,7 +438,7 @@ export function main() {
|
|||||||
(tcb: TestComponentBuilder, async) => {
|
(tcb: TestComponentBuilder, async) => {
|
||||||
var t = `<div>
|
var t = `<div>
|
||||||
<select [(ngModel)]="selectedCity">
|
<select [(ngModel)]="selectedCity">
|
||||||
<option *ngFor="#c of list" [value]="c">{{c['name']}}</option>
|
<option *ngFor="#c of list" [ng-value]="c">{{c['name']}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
@ -468,7 +470,7 @@ export function main() {
|
|||||||
(tcb: TestComponentBuilder, async) => {
|
(tcb: TestComponentBuilder, async) => {
|
||||||
var t = `<div>
|
var t = `<div>
|
||||||
<select [(ngModel)]="selectedCity">
|
<select [(ngModel)]="selectedCity">
|
||||||
<option *ngFor="#c of list" [value]="c">{{c['name']}}</option>
|
<option *ngFor="#c of list" [ng-value]="c">{{c['name']}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
@ -496,23 +498,23 @@ export function main() {
|
|||||||
(tcb: TestComponentBuilder, async) => {
|
(tcb: TestComponentBuilder, async) => {
|
||||||
var t = `<div>
|
var t = `<div>
|
||||||
<select [(ngModel)]="selectedCity">
|
<select [(ngModel)]="selectedCity">
|
||||||
<option *ngFor="#c of list" [value]="c">{{c}}</option>
|
<option *ngFor="#c of list" [ng-value]="c">{{c}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>`;
|
</div>`;
|
||||||
tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((fixture) => {
|
tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((fixture) => {
|
||||||
|
|
||||||
var testComp: MyComp = fixture.debugElement.componentInstance;
|
var testComp: MyComp = fixture.debugElement.componentInstance;
|
||||||
testComp.list = ["SF", "NYC"];
|
testComp.list = [{"name": "SF"}, {"name": "NYC"}];
|
||||||
testComp.selectedCity = testComp.list[1];
|
testComp.selectedCity = testComp.list[1];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
var select = fixture.debugElement.query(By.css("select"));
|
var select = fixture.debugElement.query(By.css("select"));
|
||||||
expect(select.nativeElement.value).toEqual("1: NYC");
|
expect(select.nativeElement.value).toEqual("1: Object");
|
||||||
|
|
||||||
testComp.list.pop();
|
testComp.list.pop();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(select.nativeElement.value).not.toEqual("1: NYC");
|
expect(select.nativeElement.value).not.toEqual("1: Object");
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
@ -522,7 +524,7 @@ export function main() {
|
|||||||
(tcb: TestComponentBuilder, async) => {
|
(tcb: TestComponentBuilder, async) => {
|
||||||
var t = `<div>
|
var t = `<div>
|
||||||
<select [(ngModel)]="selectedCity">
|
<select [(ngModel)]="selectedCity">
|
||||||
<option *ngFor="#c of list; trackBy:customTrackBy" [value]="c">{{c}}</option>
|
<option *ngFor="#c of list; trackBy:customTrackBy" [ng-value]="c">{{c}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
@ -530,12 +532,12 @@ export function main() {
|
|||||||
|
|
||||||
var testComp = fixture.debugElement.componentInstance;
|
var testComp = fixture.debugElement.componentInstance;
|
||||||
|
|
||||||
testComp.list = ["SF", "NYC"];
|
testComp.list = [{"name": "SF"}, {"name": "NYC"}];
|
||||||
testComp.selectedCity = testComp.list[0];
|
testComp.selectedCity = testComp.list[0];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
testComp.list[1] = "Buffalo";
|
testComp.list[1] = "Buffalo";
|
||||||
testComp.selectedCity = "Buffalo";
|
testComp.selectedCity = testComp.list[1];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
var select = fixture.debugElement.query(By.css("select"));
|
var select = fixture.debugElement.query(By.css("select"));
|
||||||
@ -552,7 +554,7 @@ export function main() {
|
|||||||
(tcb: TestComponentBuilder, async) => {
|
(tcb: TestComponentBuilder, async) => {
|
||||||
var t = `<div>
|
var t = `<div>
|
||||||
<select [(ngModel)]="selectedCity">
|
<select [(ngModel)]="selectedCity">
|
||||||
<option *ngFor="#c of list" [value]="c">{{c}}</option>
|
<option *ngFor="#c of list" [ng-value]="c">{{c}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
@ -560,17 +562,17 @@ export function main() {
|
|||||||
|
|
||||||
var testComp = fixture.debugElement.componentInstance;
|
var testComp = fixture.debugElement.componentInstance;
|
||||||
|
|
||||||
testComp.list = ["NYC", "SF", "SF"];
|
testComp.list = [{"name": "NYC"}, {"name": "SF"}, {"name": "SF"}];
|
||||||
testComp.selectedCity = testComp.list[0];
|
testComp.selectedCity = testComp.list[0];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
testComp.selectedCity = "SF";
|
testComp.selectedCity = testComp.list[1];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
var select = fixture.debugElement.query(By.css("select"));
|
var select = fixture.debugElement.query(By.css("select"));
|
||||||
var firstSF = fixture.debugElement.queryAll(By.css("option"))[1];
|
var firstSF = fixture.debugElement.queryAll(By.css("option"))[1];
|
||||||
|
|
||||||
expect(select.nativeElement.value).toEqual("1: SF");
|
expect(select.nativeElement.value).toEqual("1: Object");
|
||||||
expect(firstSF.nativeElement.selected).toBe(true);
|
expect(firstSF.nativeElement.selected).toBe(true);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
@ -581,7 +583,7 @@ export function main() {
|
|||||||
(tcb: TestComponentBuilder, async) => {
|
(tcb: TestComponentBuilder, async) => {
|
||||||
var t = `<div>
|
var t = `<div>
|
||||||
<select [(ngModel)]="selectedCity">
|
<select [(ngModel)]="selectedCity">
|
||||||
<option *ngFor="#c of list" [value]="c">{{c['name']}}</option>
|
<option *ngFor="#c of list" [ng-value]="c">{{c['name']}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
|
@ -780,6 +780,7 @@ const COMMON = [
|
|||||||
'NgSelectOption.constructor(_element:ElementRef, _renderer:Renderer, _select:SelectControlValueAccessor)',
|
'NgSelectOption.constructor(_element:ElementRef, _renderer:Renderer, _select:SelectControlValueAccessor)',
|
||||||
'NgSelectOption.id:string',
|
'NgSelectOption.id:string',
|
||||||
'NgSelectOption.ngOnDestroy():any',
|
'NgSelectOption.ngOnDestroy():any',
|
||||||
|
'NgSelectOption.ngValue=(value:any)',
|
||||||
'NgSelectOption.value=(value:any)',
|
'NgSelectOption.value=(value:any)',
|
||||||
'NgStyle',
|
'NgStyle',
|
||||||
'NgStyle.constructor(_differs:KeyValueDiffers, _ngEl:ElementRef, _renderer:Renderer)',
|
'NgStyle.constructor(_differs:KeyValueDiffers, _ngEl:ElementRef, _renderer:Renderer)',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user