mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
committed by
Jeremy Elbourn
parent
0b31d25b14
commit
6aff4cce71
@@ -21,6 +21,15 @@ A dynamic example, populated from a `data` variable:
|
||||
</md-radio-group>
|
||||
```
|
||||
|
||||
A dynamic example for use inside a form showing support for `[(ngModel)]`:
|
||||
```html
|
||||
<md-radio-group [(ngModel)]="chosenOption">
|
||||
<md-radio-button *ngFor="#o of options" [value]="o.value">
|
||||
{{o.label}}
|
||||
</md-radio-button>
|
||||
</md-radio-group>
|
||||
```
|
||||
|
||||
## `<md-radio-group>`
|
||||
### Properties
|
||||
|
||||
|
||||
@@ -258,6 +258,68 @@ export function main() {
|
||||
});
|
||||
}).then(done);
|
||||
});
|
||||
|
||||
it('should bind value to model without initial value', (done: () => void) => {
|
||||
builder
|
||||
.overrideTemplate(TestApp, `
|
||||
<md-radio-group [(ngModel)]="choice">
|
||||
<md-radio-button [value]="0"></md-radio-button>
|
||||
<md-radio-button [value]="1"></md-radio-button>
|
||||
</md-radio-group>`)
|
||||
.createAsync(TestApp)
|
||||
.then((fixture) => {
|
||||
fakeAsync(function() {
|
||||
let buttons = fixture.debugElement.queryAll(By.css('md-radio-button'));
|
||||
let group = fixture.debugElement.query(By.css('md-radio-group'));
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(buttons[0].componentInstance.checked).toBe(false);
|
||||
expect(buttons[1].componentInstance.checked).toBe(false);
|
||||
expect(fixture.componentInstance.choice).toBe(undefined);
|
||||
|
||||
group.componentInstance.selected = buttons[0].componentInstance;
|
||||
fixture.detectChanges();
|
||||
expect(isSinglySelected(buttons[0], buttons)).toBe(true);
|
||||
expect(fixture.componentInstance.choice).toBe(0);
|
||||
|
||||
group.componentInstance.selected = buttons[1].componentInstance;
|
||||
fixture.detectChanges();
|
||||
expect(isSinglySelected(buttons[1], buttons)).toBe(true);
|
||||
expect(fixture.componentInstance.choice).toBe(1);
|
||||
});
|
||||
}).then(done);
|
||||
});
|
||||
|
||||
it('should bind value to model with initial value', (done: () => void) => {
|
||||
builder
|
||||
.overrideTemplate(TestAppWithInitialValue, `
|
||||
<md-radio-group [(ngModel)]="choice">
|
||||
<md-radio-button [value]="0"></md-radio-button>
|
||||
<md-radio-button [value]="1"></md-radio-button>
|
||||
</md-radio-group>`)
|
||||
.createAsync(TestAppWithInitialValue)
|
||||
.then((fixture) => {
|
||||
fakeAsync(function() {
|
||||
let buttons = fixture.debugElement.queryAll(By.css('md-radio-button'));
|
||||
let group = fixture.debugElement.query(By.css('md-radio-group'));
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(isSinglySelected(buttons[1], buttons)).toBe(true);
|
||||
expect(fixture.componentInstance.choice).toBe(1);
|
||||
|
||||
group.componentInstance.selected = buttons[0].componentInstance;
|
||||
fixture.detectChanges();
|
||||
expect(isSinglySelected(buttons[0], buttons)).toBe(true);
|
||||
expect(fixture.componentInstance.choice).toBe(0);
|
||||
|
||||
group.componentInstance.selected = buttons[1].componentInstance;
|
||||
fixture.detectChanges();
|
||||
expect(isSinglySelected(buttons[1], buttons)).toBe(true);
|
||||
expect(fixture.componentInstance.choice).toBe(1);
|
||||
});
|
||||
}).then(done);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -289,4 +351,16 @@ function createEvent(name: string): Event {
|
||||
providers: [MdRadioDispatcher],
|
||||
template: ''
|
||||
})
|
||||
class TestApp {}
|
||||
class TestApp {
|
||||
choice: number;
|
||||
}
|
||||
|
||||
/** Test component. */
|
||||
@Component({
|
||||
directives: [MdRadioButton, MdRadioGroup],
|
||||
providers: [MdRadioDispatcher],
|
||||
template: ''
|
||||
})
|
||||
class TestAppWithInitialValue {
|
||||
choice: number = 1;
|
||||
}
|
||||
|
||||
@@ -10,14 +10,31 @@ import {
|
||||
OnInit,
|
||||
Optional,
|
||||
Output,
|
||||
Provider,
|
||||
QueryList,
|
||||
ViewEncapsulation,
|
||||
forwardRef
|
||||
} from 'angular2/core';
|
||||
|
||||
import {
|
||||
NG_VALUE_ACCESSOR,
|
||||
ControlValueAccessor
|
||||
} from 'angular2/src/common/forms/directives/control_value_accessor';
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
import {MdRadioDispatcher} from './radio_dispatcher';
|
||||
export {MdRadioDispatcher} from './radio_dispatcher';
|
||||
|
||||
/**
|
||||
* Provider Expression that allows md-radio-group to register as a ControlValueAccessor. This
|
||||
* allows it to support [(ngModel)] and ngControl.
|
||||
*/
|
||||
const MD_RADIO_GROUP_CONTROL_VALUE_ACCESSOR = CONST_EXPR(new Provider(
|
||||
NG_VALUE_ACCESSOR, {
|
||||
useExisting: forwardRef(() => MdRadioGroup),
|
||||
multi: true
|
||||
}));
|
||||
|
||||
// TODO(mtlin):
|
||||
// Ink ripple is currently placeholder.
|
||||
// Determine motion spec for button transitions.
|
||||
@@ -36,11 +53,12 @@ export class MdRadioChange {
|
||||
|
||||
@Directive({
|
||||
selector: 'md-radio-group',
|
||||
providers: [MD_RADIO_GROUP_CONTROL_VALUE_ACCESSOR],
|
||||
host: {
|
||||
'role': 'radiogroup',
|
||||
},
|
||||
})
|
||||
export class MdRadioGroup implements AfterContentInit {
|
||||
export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
|
||||
/** The value for the radio group. Should match currently selected button. */
|
||||
private _value: any = null;
|
||||
|
||||
@@ -53,6 +71,11 @@ export class MdRadioGroup implements AfterContentInit {
|
||||
/** The currently selected radio button. Should match value. */
|
||||
private _selected: MdRadioButton = null;
|
||||
|
||||
/** Change event subscription set up by registerOnChange (ControlValueAccessor). */
|
||||
private _changeSubscription: {unsubscribe: () => any} = null;
|
||||
|
||||
onTouched: () => any = () => {};
|
||||
|
||||
/** Event emitted when the group value changes. */
|
||||
@Output()
|
||||
change: EventEmitter<MdRadioChange> = new EventEmitter();
|
||||
@@ -155,6 +178,25 @@ export class MdRadioGroup implements AfterContentInit {
|
||||
|
||||
selected.checked = true;
|
||||
}
|
||||
|
||||
/** Implemented as part of ControlValueAccessor. */
|
||||
writeValue(value: any) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/** Implemented as part of ControlValueAccessor. */
|
||||
registerOnChange(fn: any) {
|
||||
if (this._changeSubscription) {
|
||||
this._changeSubscription.unsubscribe();
|
||||
}
|
||||
this._changeSubscription = <{unsubscribe: () => any}>this.change.subscribe(
|
||||
(changeEvent: MdRadioChange) => { fn(changeEvent.value); });
|
||||
}
|
||||
|
||||
/** Implemented as part of ControlValueAccessor. */
|
||||
registerOnTouched(fn: any) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -210,6 +252,10 @@ export class MdRadioButton implements OnInit {
|
||||
if (this.id == null) {
|
||||
this.id = `md-radio-${_uniqueIdCounter++}`;
|
||||
}
|
||||
|
||||
if (this.radioGroup && this._value == this.radioGroup.value) {
|
||||
this._checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<h1>Basic Example</h1>
|
||||
<section class="demo-section">
|
||||
<md-radio-button name="group1">Option 1</md-radio-button>
|
||||
<md-radio-button name="group1">Option 2</md-radio-button>
|
||||
<md-radio-button name="group1" disabled="true">Option 3 (disabled)</md-radio-button>
|
||||
</section>
|
||||
<h1>Dynamic Example</h1>
|
||||
<section class="demo-section">
|
||||
<div>
|
||||
<span>isDisabled: {{isDisabled}}</span>
|
||||
@@ -16,3 +18,13 @@
|
||||
<md-radio-button value="option_3">Option 3</md-radio-button>
|
||||
</md-radio-group>
|
||||
</section>
|
||||
<h1>Favorite Season Example</h1>
|
||||
<h2>Dynamic Example with two-way data-binding</h2>
|
||||
<section class="demo-section">
|
||||
<md-radio-group name="more_options" [(ngModel)]="favoriteSeason">
|
||||
<md-radio-button *ngFor="#season of seasonOptions" name="more_options" [value]="season">
|
||||
{{season}}
|
||||
</md-radio-button>
|
||||
</md-radio-group>
|
||||
<p>Your favorite season is: {{favoriteSeason}}</p>
|
||||
</section>
|
||||
|
||||
@@ -11,4 +11,11 @@ import {MdRadioDispatcher} from '../../components/radio/radio_dispatcher';
|
||||
})
|
||||
export class RadioDemo {
|
||||
isDisabled: boolean = false;
|
||||
favoriteSeason: string = 'Autumn';
|
||||
seasonOptions = [
|
||||
'Winter',
|
||||
'Spring',
|
||||
'Summer',
|
||||
'Autumn',
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user