feat(Change Detection): Add support for keyed access

This commit is contained in:
Victor Berchet 2014-12-02 13:14:07 +01:00
parent 7bc282d15e
commit 7cb93fd59e
4 changed files with 38 additions and 6 deletions

View File

@ -10,7 +10,8 @@ import {
RECORD_TYPE_PROPERTY
} from './record';
import {FIELD, IMPLEMENTS, isBlank, isPresent, int, toBool, autoConvertAdd, BaseException} from 'facade/lang';
import {FIELD, IMPLEMENTS, isBlank, isPresent, int, toBool, autoConvertAdd, BaseException,
NumberWrapper} from 'facade/lang';
import {List, Map, ListWrapper, MapWrapper} from 'facade/collection';
import {AST, AccessMember, ImplicitReceiver, AstVisitor, LiteralPrimitive,
Binary, Formatter, MethodCall, FunctionCall, PrefixNot, Conditional,
@ -443,7 +444,12 @@ class ProtoRecordCreator {
this.add(record);
}
visitKeyedAccess(ast:KeyedAccess, dest) {}
visitKeyedAccess(ast:KeyedAccess, dest) {
var record = this.construct(RECORD_TYPE_INVOKE_METHOD, _keyedAccess, 1, null, dest);
ast.obj.visit(this, new Destination(record, null));
ast.key.visit(this, new Destination(record, 0));
this.add(record);
}
visitLiteralArray(ast:LiteralArray, dest) {
var length = ast.expressions.length;
@ -527,6 +533,7 @@ function _operation_greater_or_equals_then(left, right) {return left >= right;}
function _operation_logical_and(left, right) {return left && right;}
function _operation_logical_or(left, right) {return left || right;}
function _cond(cond, trueVal, falseVal) {return cond ? trueVal : falseVal;}
function _arrayFn(length:int) {
switch (length) {
case 0: return () => [];
@ -542,6 +549,7 @@ function _arrayFn(length:int) {
default: throw new BaseException(`Does not support literal arrays with more than 9 elements`);
}
}
function _mapFn(keys:List, length:int) {
function buildMap(values) {
var res = MapWrapper.create();
@ -571,4 +579,9 @@ function _mapGetter(key) {
return function(map) {
return MapWrapper.get(map, key);
}
}
}
function _keyedAccess(obj, args) {
var key = args[0];
return obj instanceof Map ? MapWrapper.get(obj, key):obj[key];
}

View File

@ -153,6 +153,15 @@ export function main() {
expect(executeWatch('m', '1 > 2 ? 1 : 2')).toEqual(['m=2']);
});
describe("keyed access", () => {
it("should support accessing a list item", () => {
expect(executeWatch('array[0]', '["foo", "bar"][0]')).toEqual(['array[0]=foo']);
});
it("should support accessing a map item", () => {
expect(executeWatch('map[foo]', '{"foo": "bar"}["foo"]')).toEqual(['map[foo]=bar']);
});
});
describe("formatters", () => {
it("should support formatters", () => {
var formatters = MapWrapper.createFromPairs([
@ -269,6 +278,10 @@ class LoggingDispatcher extends WatchGroupDispatcher {
onRecordChange(record:Record, context) {
ListWrapper.push(this.loggedValues, record.currentValue);
ListWrapper.push(this.log, context + '=' + record.currentValue.toString());
ListWrapper.push(this.log, context + '=' + this._asString(record.currentValue));
}
_asString(value) {
return (value === null ? 'null' : value.toString());
}
}

View File

@ -109,6 +109,8 @@ class NumberWrapper {
static get NaN => double.NAN;
static bool isNaN(num value) => value.isNaN;
static bool isInteger(value) => value is int;
}
class RegExpWrapper {
@ -161,4 +163,4 @@ dynamic getMapKey(value) {
normalizeBlank(obj) {
return isBlank(obj) ? null : obj;
}
}

View File

@ -136,6 +136,10 @@ export class NumberWrapper {
static get NaN():number {
return NaN;
}
static isInteger(value):boolean {
return Number.isInteger(value);
}
}
export function int() {};
@ -197,4 +201,4 @@ export function getMapKey(value) {
export function normalizeBlank(obj) {
return isBlank(obj) ? null : obj;
}
}