Skip to content

Commit 0e2a1a4

Browse files
committed
fix(renderer): stop performing value conversions
These conversions are now handled by core modules. The conversions performed in the renderer and value accessors are no longer needed. fixes #799
1 parent 1c7cbce commit 0e2a1a4

14 files changed

+48
-132
lines changed

Diff for: nativescript-angular/common/utils.ts

-16
This file was deleted.

Diff for: nativescript-angular/directives/tab-view.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
import { TabView, TabViewItem } from "tns-core-modules/ui/tab-view";
1111

1212
import { CommentNode } from "../element-types";
13-
import { convertToInt } from "../common/utils";
1413
import { rendererLog } from "../trace";
1514
import { isBlank } from "../lang-facade";
1615

@@ -28,7 +27,7 @@ export class TabViewDirective implements AfterViewInit {
2827
}
2928

3029
set selectedIndex(value) {
31-
this._selectedIndex = convertToInt(value);
30+
this._selectedIndex = value;
3231
if (this.viewInitialized) {
3332
this.tabView.selectedIndex = this._selectedIndex;
3433
}

Diff for: nativescript-angular/lang-facade.ts

-4
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ export function isBlank(obj: any): boolean {
1111
return obj === undefined || obj === null;
1212
}
1313

14-
export function isNumber(obj: any): boolean {
15-
return typeof obj === 'number';
16-
}
17-
1814
export function isDate(obj: any): obj is Date {
1915
return obj instanceof Date && !isNaN(obj.valueOf());
2016
}

Diff for: nativescript-angular/value-accessors/checked-value-accessor.ts

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
3-
import { isBlank } from "../lang-facade";
43
import { BaseValueAccessor } from "./base-value-accessor";
54
import { Switch } from "tns-core-modules/ui/switch";
65

@@ -34,15 +33,7 @@ export class CheckedValueAccessor extends BaseValueAccessor<Switch> { // tslint:
3433
}
3534

3635
writeValue(value: any): void {
37-
let normalizedValue = false;
38-
if (!isBlank(value)) {
39-
if (typeof value === "string") {
40-
normalizedValue = value.toLowerCase() === "true" ? true : false;
41-
} else {
42-
normalizedValue = !!value;
43-
}
44-
}
45-
this.view.checked = normalizedValue;
36+
this.view.checked = value;
4637
}
4738

4839
registerOnTouched(fn: () => void): void { this.onTouched = fn; }

Diff for: nativescript-angular/value-accessors/date-value-accessor.ts

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
3-
import { isBlank, isDate } from "../lang-facade";
43
import { BaseValueAccessor } from "./base-value-accessor";
54
import { DatePicker } from "tns-core-modules/ui/date-picker";
65

@@ -34,19 +33,7 @@ export class DateValueAccessor extends BaseValueAccessor<DatePicker> { // tslint
3433
}
3534

3635
writeValue(value: any): void {
37-
let normalizedValue = isBlank(value) ? new Date() : value;
38-
if (!isDate(normalizedValue)) {
39-
if (typeof normalizedValue === "string") {
40-
normalizedValue = new Date(normalizedValue);
41-
} else if (typeof normalizedValue === "number") {
42-
normalizedValue = new Date(normalizedValue);
43-
}
44-
45-
if (!isDate(normalizedValue)) {
46-
normalizedValue = new Date();
47-
}
48-
}
49-
this.view.date = normalizedValue;
36+
this.view.date = value;
5037
}
5138

5239
registerOnTouched(fn: () => void): void { this.onTouched = fn; }

Diff for: nativescript-angular/value-accessors/number-value-accessor.ts

+1-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
3-
import { isBlank, isNumber } from "../lang-facade";
43
import { BaseValueAccessor } from "./base-value-accessor";
54
import { Slider } from "tns-core-modules/ui/slider";
65

@@ -34,18 +33,7 @@ export class NumberValueAccessor extends BaseValueAccessor<Slider> { // tslint:d
3433
}
3534

3635
writeValue(value: any): void {
37-
let normalizedValue;
38-
if (isBlank(value)) {
39-
normalizedValue = 0;
40-
} else {
41-
if (isNumber(value)) {
42-
normalizedValue = value;
43-
} else {
44-
let parsedValue = Number(value);
45-
normalizedValue = isNaN(parsedValue) ? 0 : parsedValue;
46-
}
47-
}
48-
this.view.value = normalizedValue;
36+
this.view.value = value;
4937
}
5038

5139
registerOnTouched(fn: () => void): void { this.onTouched = fn; }

Diff for: nativescript-angular/value-accessors/selectedIndex-value-accessor.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Directive, ElementRef, forwardRef, AfterViewInit, HostListener } from "
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
33
import { BaseValueAccessor } from "./base-value-accessor";
44
import { View } from "tns-core-modules/ui/core/view";
5-
import { convertToInt } from "../common/utils";
65

76
const SELECTED_INDEX_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
87
useExisting: forwardRef(() => SelectedIndexValueAccessor), multi: true};
@@ -35,19 +34,19 @@ export class SelectedIndexValueAccessor extends BaseValueAccessor<SelectableView
3534
super(elementRef.nativeElement);
3635
}
3736

38-
private _normalizedValue: number;
37+
private value: number;
3938
private viewInitialized: boolean;
4039

4140
writeValue(value: any): void {
42-
this._normalizedValue = convertToInt(value);
41+
this.value = value;
4342
if (this.viewInitialized) {
44-
this.view.selectedIndex = this._normalizedValue;
43+
this.view.selectedIndex = this.value;
4544
}
4645
}
4746

4847
ngAfterViewInit() {
4948
this.viewInitialized = true;
50-
this.view.selectedIndex = this._normalizedValue;
49+
this.view.selectedIndex = this.value;
5150
}
5251

5352
registerOnTouched(fn: () => void): void { this.onTouched = fn; }

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
3-
import { isBlank } from "../lang-facade";
43
import { BaseValueAccessor } from "./base-value-accessor";
54
import { View } from "tns-core-modules/ui/core/view";
65

@@ -36,8 +35,7 @@ export class TextValueAccessor extends BaseValueAccessor<TextView> { // tslint:d
3635
}
3736

3837
writeValue(value: any): void {
39-
let normalizedValue = isBlank(value) ? "" : value.toString();
40-
this.view.text = normalizedValue;
38+
this.view.text = value;
4139
}
4240

4341
registerOnTouched(fn: () => void): void { this.onTouched = fn; }

Diff for: nativescript-angular/value-accessors/time-value-accessor.ts

+1-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
3-
import { isBlank, isDate } from "../lang-facade";
43
import { BaseValueAccessor } from "./base-value-accessor";
54
import { TimePicker } from "tns-core-modules/ui/time-picker";
65

@@ -34,18 +33,7 @@ export class TimeValueAccessor extends BaseValueAccessor<TimePicker> { // tslint
3433
}
3534

3635
writeValue(value: any): void {
37-
let normalizedValue = isBlank(value) ? new Date() : value;
38-
if (!isDate(normalizedValue)) {
39-
if (typeof normalizedValue === "string") {
40-
normalizedValue = new Date(normalizedValue);
41-
} else if (typeof normalizedValue === "number") {
42-
normalizedValue = new Date(normalizedValue);
43-
}
44-
if (!isDate(normalizedValue)) {
45-
normalizedValue = new Date();
46-
}
47-
}
48-
this.view.time = normalizedValue;
36+
this.view.time = value;
4937
}
5038

5139
registerOnTouched(fn: () => void): void { this.onTouched = fn; }

Diff for: nativescript-angular/view-util.ts

+16-24
Original file line numberDiff line numberDiff line change
@@ -207,41 +207,32 @@ export class ViewUtil {
207207

208208

209209
private setPropertyInternal(view: NgView, attributeName: string, value: any): void {
210-
traceLog("Setting attribute: " + attributeName);
211-
212-
let propMap = this.getProperties(view);
210+
traceLog(`Setting attribute: ${attributeName}=${value} to ${view}`);
213211

214212
if (attributeName === "class") {
215213
this.setClasses(view, value);
216-
} else if (XML_ATTRIBUTES.indexOf(attributeName) !== -1) {
217-
view._applyXmlAttribute(attributeName, value);
218-
} else if (propMap.has(attributeName)) {
219-
// We have a lower-upper case mapped property.
220-
let propertyName = propMap.get(attributeName);
221-
view[propertyName] = this.convertValue(value);
222-
} else {
223-
// Unknown attribute value -- just set it to our object as is.
224-
view[attributeName] = this.convertValue(value);
214+
return;
225215
}
226-
}
227216

228-
private convertValue(value: any): any {
229-
if (typeof (value) !== "string" || value === "") {
230-
return value;
217+
if (XML_ATTRIBUTES.indexOf(attributeName) !== -1) {
218+
view._applyXmlAttribute(attributeName, value);
219+
return;
231220
}
232221

233-
let valueAsNumber = +value;
234-
if (!isNaN(valueAsNumber)) {
235-
return valueAsNumber;
236-
} else if (value && (value.toLowerCase() === "true" || value.toLowerCase() === "false")) {
237-
return value.toLowerCase() === "true" ? true : false;
238-
} else {
239-
return value;
222+
const propMap = this.getProperties(view);
223+
const propertyName = propMap.get(attributeName);
224+
if (propertyName) {
225+
// We have a lower-upper case mapped property.
226+
view[propertyName] = value;
227+
return;
240228
}
229+
230+
// Unknown attribute value -- just set it to our object as is.
231+
view[attributeName] = value;
241232
}
242233

243234
private getProperties(instance: any): Map<string, string> {
244-
let type = instance && instance.constructor;
235+
const type = instance && instance.constructor;
245236
if (!type) {
246237
return new Map<string, string>();
247238
}
@@ -253,6 +244,7 @@ export class ViewUtil {
253244
}
254245
propertyMaps.set(type, propMap);
255246
}
247+
256248
return propertyMaps.get(type);
257249
}
258250

Diff for: tests/app/tests/property-sets.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,24 @@ describe("setting View properties", () => {
3636
assert.equal("blah", view.stringValue);
3737
});
3838

39-
it("converts number values", () => {
39+
it("doesn\'t convert number values", () => {
4040
let view = new TestView();
4141
viewUtil.setProperty(view, "numValue", "42");
42-
assert.strictEqual(42, view.numValue);
42+
assert.strictEqual("42", view.numValue);
43+
44+
viewUtil.setProperty(view, "numValue", "42.");
45+
assert.strictEqual("42.", view.numValue);
46+
4347
viewUtil.setProperty(view, "numValue", 0);
4448
assert.strictEqual(0, view.numValue);
4549
});
4650

47-
it("converts boolean values", () => {
51+
it("doesn\'t convert boolean values", () => {
4852
let view = new TestView();
4953
viewUtil.setProperty(view, "boolValue", "true");
50-
assert.strictEqual(true, view.boolValue);
54+
assert.strictEqual("true", view.boolValue);
5155
viewUtil.setProperty(view, "boolValue", "false");
52-
assert.strictEqual(false, view.boolValue);
56+
assert.strictEqual("false", view.boolValue);
5357
});
5458

5559
it("sets style values", () => {

Diff for: tests/app/tests/value-accessor-tests.ts

+11-21
Original file line numberDiff line numberDiff line change
@@ -78,72 +78,62 @@ describe("two-way binding via ng-model", () => {
7878
assert.strictEqual(42, accessor.view.value);
7979

8080
accessor.writeValue("blah");
81-
assert.strictEqual(0, accessor.view.value, "default to 0 on parse errors");
81+
assert.notEqual(accessor.view.value, accessor.view.value, "defaults to NaN on parse errors");
8282
});
8383

8484
it("converts strings to bools", () => {
8585
const accessor = new TestCheckedValueAccessor();
8686

8787
accessor.writeValue(null);
88-
assert.strictEqual(false, accessor.view.checked, "default to false on empty");
88+
assert.strictEqual(null, accessor.view.checked, "default to null on empty");
8989

9090
accessor.writeValue("true");
9191
assert.strictEqual(true, accessor.view.checked);
9292

93-
accessor.writeValue("blah");
94-
assert.strictEqual(false, accessor.view.checked, "default to false on parse errors");
93+
assert.throws(() => accessor.writeValue("blah"));
9594
});
9695

9796
it("converts strings to dates", () => {
9897
const now = new Date();
9998
const accessor = new TestDateValueAccessor();
10099

101100
accessor.writeValue(null);
102-
assert.equal(formatDate(now), formatDate(accessor.view.date), "default to now on empty");
101+
assert.equal(null, accessor.view.date, "default to null on empty");
103102

104103
accessor.writeValue("2010-03-17");
105104
assert.equal(formatDate(new Date(2010, 2, 17)), formatDate(accessor.view.date));
106-
107-
accessor.writeValue("a fortnight ago");
108-
assert.equal(formatDate(now), formatDate(accessor.view.date), "default to now on parse error");
109105
});
110106

111107
it("converts strings to int selection", () => {
112108
const accessor = new TestSelectedIndexValueAccessor();
113109

114110
accessor.writeValue(null);
115111
accessor.ngAfterViewInit();
116-
assert.strictEqual(0, accessor.view.selectedIndex, "default to 0 on empty");
112+
assert.strictEqual(null, accessor.view.selectedIndex, "default to null on empty");
117113

118114
accessor.writeValue("3");
119115
accessor.ngAfterViewInit();
120116
assert.strictEqual(3, accessor.view.selectedIndex);
121117

122118
accessor.writeValue("blah");
123119
accessor.ngAfterViewInit();
124-
assert.strictEqual(0, accessor.view.selectedIndex, "default to 0 on parse errors");
120+
assert.notEqual(accessor.view.selectedIndex, accessor.view.selectedIndex,
121+
"default to NaN on parse errors");
125122
});
126123

127124
it("converts strings to times", () => {
128-
const now = new Date();
129125
const accessor = new TestTimeValueAccessor();
130126

131-
accessor.writeValue(null);
132-
assert.equal(formatTime(now), formatTime(accessor.view.time), "default to now on empty");
133-
134-
accessor.writeValue("2010/03/17 12:54");
135-
assert.equal(formatTime(new Date(2010, 2, 17, 12, 54)), formatTime(accessor.view.time));
136-
137-
accessor.writeValue("three hours from now");
138-
assert.equal(formatTime(now), formatTime(accessor.view.time), "default to now on parse error");
127+
assert.throws(() => accessor.writeValue(null));
128+
assert.throws(() => accessor.writeValue("2010/03/17 12:54"));
129+
assert.throws(() => accessor.writeValue("three hours from now"));
139130
});
140131

141132
it("converts values to text", () => {
142-
const now = new Date();
143133
const accessor = new TestTextValueAccessor();
144134

145135
accessor.writeValue(null);
146-
assert.equal("", accessor.view.text);
136+
assert.equal(null, accessor.view.text, "defaults to null on empty");
147137

148138
accessor.writeValue("blah");
149139
assert.equal("blah", accessor.view.text);

Diff for: tests/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"appium-android": "tns build android && npm run run-appium-android",
7070
"run-appium-android": "nativescript-dev-appium android",
7171
"appium-ios-simulator": "tns build ios && nativescript-dev-appium ios-simulator",
72-
"tslint": "tslint --project tsconfig.json --config tslint.json"
72+
"tslint": "tslint --project tsconfig.json --config tslint.json",
73+
"appium": "nativescript-dev-appium"
7374
}
7475
}

Diff for: tests/references.d.ts

-1
This file was deleted.

0 commit comments

Comments
 (0)