vsavkin 3cda7128d0 cleanup(di): renamed viewInjector and hostInjector
BREAKING CHANGE
    Replace viewInjector with viewBindings
    Replace hostInjector with bindings
2015-07-31 09:49:51 -07:00

147 lines
4.1 KiB
TypeScript

import {
PromiseWrapper,
ObservableWrapper,
EventEmitter,
PromiseCompleter
} from 'angular2/src/facade/async';
import {StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
import {isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
import {Directive} from 'angular2/annotations';
import {forwardRef, Binding} from 'angular2/di';
import {NgControl} from './ng_control';
import {Form} from './form_interface';
import {NgControlGroup} from './ng_control_group';
import {ControlContainer} from './control_container';
import {AbstractControl, ControlGroup, Control} from '../model';
import {setUpControl} from './shared';
const formDirectiveBinding =
CONST_EXPR(new Binding(ControlContainer, {toAlias: forwardRef(() => NgForm)}));
/**
* Creates and binds a form object to a DOM element.
*
* # Example
*
* ```
* @Component({selector: "signup-comp"})
* @View({
* directives: [formDirectives],
* template: `
* <form #f="form" (submit)='onSignUp(f.value)'>
* <div ng-control-group='credentials' #credentials="form">
* Login <input type='text' ng-control='login'>
* Password <input type='password' ng-control='password'>
* </div>
* <div *ng-if="!credentials.valid">Credentials are invalid</div>
*
* <div ng-control-group='personal'>
* Name <input type='text' ng-control='name'>
* </div>
* <button type='submit'>Sign Up!</button>
* </form>
* `})
* class SignupComp {
* onSignUp(value) {
* // value === {personal: {name: 'some name'},
* // credentials: {login: 'some login', password: 'some password'}}
* }
* }
*
* ```
*/
@Directive({
selector: 'form:not([ng-no-form]):not([ng-form-model]),ng-form,[ng-form]',
bindings: [formDirectiveBinding],
host: {
'(submit)': 'onSubmit()',
},
events: ['ngSubmit'],
exportAs: 'form'
})
export class NgForm extends ControlContainer implements Form {
form: ControlGroup;
ngSubmit = new EventEmitter();
constructor() {
super();
this.form = new ControlGroup({});
}
get formDirective(): Form { return this; }
get control(): ControlGroup { return this.form; }
get path(): List<string> { return []; }
get controls(): StringMap<string, AbstractControl> { return this.form.controls; }
addControl(dir: NgControl): void {
this._later(_ => {
var container = this._findContainer(dir.path);
var c = new Control();
setUpControl(c, dir);
container.addControl(dir.name, c);
c.updateValidity();
});
}
getControl(dir: NgControl): Control { return <Control>this.form.find(dir.path); }
removeControl(dir: NgControl): void {
this._later(_ => {
var container = this._findContainer(dir.path);
if (isPresent(container)) {
container.removeControl(dir.name);
container.updateValidity();
}
});
}
addControlGroup(dir: NgControlGroup): void {
this._later(_ => {
var container = this._findContainer(dir.path);
var c = new ControlGroup({});
container.addControl(dir.name, c);
c.updateValidity();
});
}
removeControlGroup(dir: NgControlGroup): void {
this._later(_ => {
var container = this._findContainer(dir.path);
if (isPresent(container)) {
container.removeControl(dir.name);
container.updateValidity();
}
});
}
getControlGroup(dir: NgControlGroup): ControlGroup {
return <ControlGroup>this.form.find(dir.path);
}
updateModel(dir: NgControl, value: any): void {
this._later(_ => {
var c = <Control>this.form.find(dir.path);
c.updateValue(value);
});
}
onSubmit(): boolean {
ObservableWrapper.callNext(this.ngSubmit, null);
return false;
}
_findContainer(path: List<string>): ControlGroup {
ListWrapper.removeLast(path);
return ListWrapper.isEmpty(path) ? this.form : <ControlGroup>this.form.find(path);
}
_later(fn) {
var c: PromiseCompleter<any> = PromiseWrapper.completer();
PromiseWrapper.then(c.promise, fn, (_) => {});
c.resolve(null);
}
}