diff --git a/modules/change_detection/src/record_range.js b/modules/change_detection/src/record_range.js index d265b08230..7ead66657c 100644 --- a/modules/change_detection/src/record_range.js +++ b/modules/change_detection/src/record_range.js @@ -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); } -} \ No newline at end of file +} + +function _keyedAccess(obj, args) { + var key = args[0]; + return obj instanceof Map ? MapWrapper.get(obj, key):obj[key]; +} diff --git a/modules/change_detection/test/change_detector_spec.js b/modules/change_detection/test/change_detector_spec.js index ecc42cf78b..66708d1110 100644 --- a/modules/change_detection/test/change_detector_spec.js +++ b/modules/change_detection/test/change_detector_spec.js @@ -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()); } } diff --git a/modules/facade/src/lang.dart b/modules/facade/src/lang.dart index 1081250722..76abd1e2ad 100644 --- a/modules/facade/src/lang.dart +++ b/modules/facade/src/lang.dart @@ -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; -} \ No newline at end of file +} diff --git a/modules/facade/src/lang.es6 b/modules/facade/src/lang.es6 index 7aa158b0e0..58f2c40f74 100644 --- a/modules/facade/src/lang.es6 +++ b/modules/facade/src/lang.es6 @@ -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; -} \ No newline at end of file +}