Skip to content

Commit 721c27c

Browse files
author
Nedyalko Nikolov
committed
Merge pull request #36 from NativeScript/nnikolov/TextValueAccessor
Added TextValueAccessor to support two-way binding via ngModel.
2 parents 0cd3651 + 02dfd55 commit 721c27c

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

Diff for: ng-sample/app/renderer-test.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import {Component, Directive, Host, ElementRef, Input} from 'angular2/core';
2+
import { Observable } from 'data/observable';
3+
import { TextValueAccessor } from './nativescript-angular/text-value-accessor';
24

35
@Component({
46
selector: 'templated-component',
@@ -24,10 +26,12 @@ export class ProgressComponent {
2426

2527
@Component({
2628
selector: 'renderer-test',
27-
directives: [TemplatedComponent, ProgressComponent],
29+
directives: [TemplatedComponent, ProgressComponent, TextValueAccessor],
2830
template: `
2931
<StackLayout orientation='vertical'>
3032
<Progress value="50" style="color: red"></Progress>
33+
<Label [text]='model.test'></Label>
34+
<TextField #name [ngModel]='model.test' (ngModelChange)="model.test=setUpperCase($event)" fontSize='20' padding='20'></TextField>
3135
<Label [class.valid]="isValid" [class.invalid]="!isValid" text='Name' fontSize='20' verticalAlignment='center' padding='20'></Label>
3236
<TextField #name text='John' fontSize='20' padding='20'></TextField>
3337
<Button [text]='buttonText' (tap)='onSave($event, name.text, $el)'></Button>
@@ -49,12 +53,14 @@ export class RendererTest {
4953
public moreDetailsText: string = "";
5054
public detailLines: Array<string> = [];
5155
public isValid: boolean = true;
56+
public model: Observable;
5257

5358
constructor() {
5459
this.buttonText = 'Save...'
5560
this.showDetails = true;
5661
this.detailsText = 'plain ng-if directive \ndetail 1-2-3...';
5762
this.moreDetailsText = 'More details:';
63+
this.model = new Observable({'test': 'Jack'});
5864

5965
this.detailLines = [
6066
"ngFor inside a ngIf 1",
@@ -67,8 +73,22 @@ export class RendererTest {
6773
alert(name);
6874
}
6975

76+
testLoaded($event) {
77+
console.log("testLoaded called with event args: " + $event);
78+
}
79+
7080
onToggleDetails() {
7181
console.log('onToggleDetails current: ' + this.showDetails);
7282
this.showDetails = !this.showDetails;
7383
}
84+
85+
setUpperCase($event) {
86+
if ($event.value && $event.value.toUpperCase) {
87+
return $event.value.toUpperCase();
88+
}
89+
if (typeof $event === "string") {
90+
return $event.toUpperCase();
91+
}
92+
return $event;
93+
}
7494
}

Diff for: src/nativescript-angular/text-value-accessor.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {Directive, ElementRef, Renderer, Self, forwardRef, Provider} from 'angular2/core';
2+
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from 'angular2/src/common/forms/directives/control_value_accessor';
3+
import {isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
4+
5+
const TEXT_VALUE_ACCESSOR = CONST_EXPR(new Provider(
6+
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => TextValueAccessor), multi: true}));
7+
8+
/**
9+
* The accessor for writing a text and listening to changes that is used by the
10+
* {@link NgModel}, {@link NgFormControl}, and {@link NgControlName} directives.
11+
*
12+
* ### Example
13+
* ```
14+
* <TextField [(ngModel)]='model.test'>
15+
* ```
16+
*/
17+
@Directive({
18+
selector: 'TextField[ngModel]',
19+
// TODO: vsavkin replace the above selector with the one below it once
20+
// https://github.com/angular/angular/issues/3011 is implemented
21+
// selector: '[ngControl],[ngModel],[ngFormControl]',
22+
host: {'(textChange)': 'onChange($event.value)'},
23+
bindings: [TEXT_VALUE_ACCESSOR]
24+
})
25+
export class TextValueAccessor implements ControlValueAccessor {
26+
onChange = (_) => {};
27+
onTouched = () => {};
28+
29+
constructor(private _renderer: Renderer, private _elementRef: ElementRef) { }
30+
31+
writeValue(value: any): void {
32+
var normalizedValue = isBlank(value) ? '' : value;
33+
this._renderer.setElementProperty(this._elementRef.nativeElement, 'text', normalizedValue);
34+
}
35+
36+
registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
37+
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
38+
}

0 commit comments

Comments
 (0)