Sfoglia il codice sorgente

fix #251 get/set for keypaths with brackets

Evan You 12 anni fa
parent
commit
163f435153
2 ha cambiato i file con 35 aggiunte e 7 eliminazioni
  1. 21 7
      src/utils.js
  2. 14 0
      test/unit/specs/utils.js

+ 21 - 7
src/utils.js

@@ -1,10 +1,12 @@
-var config    = require('./config'),
-    toString  = ({}).toString,
-    win       = window,
-    console   = win.console,
-    def       = Object.defineProperty,
-    OBJECT    = 'object',
-    THIS_RE   = /[^\w]this[^\w]/,
+var config       = require('./config'),
+    toString     = ({}).toString,
+    win          = window,
+    console      = win.console,
+    def          = Object.defineProperty,
+    OBJECT       = 'object',
+    THIS_RE      = /[^\w]this[^\w]/,
+    BRACKET_RE_S = /\['([^']+)'\]/g,
+    BRACKET_RE_D = /\["([^"]+)"\]/g,
     hasClassList = 'classList' in document.documentElement,
     ViewModel // late def
 
@@ -13,6 +15,16 @@ var defer =
     win.webkitRequestAnimationFrame ||
     win.setTimeout
 
+/**
+ *  Normalize keypath with possible brackets into dot notations
+ */
+function normalizeKeypath (key) {
+    return key.indexOf('[') < 0
+        ? key
+        : key.replace(BRACKET_RE_S, '.$1')
+             .replace(BRACKET_RE_D, '.$1')
+}
+
 var utils = module.exports = {
 
     /**
@@ -25,6 +37,7 @@ var utils = module.exports = {
      */
     get: function (obj, key) {
         /* jshint eqeqeq: false */
+        key = normalizeKeypath(key)
         if (key.indexOf('.') < 0) {
             return obj[key]
         }
@@ -41,6 +54,7 @@ var utils = module.exports = {
      */
     set: function (obj, key, val) {
         /* jshint eqeqeq: false */
+        key = normalizeKeypath(key)
         if (key.indexOf('.') < 0) {
             obj[key] = val
             return

+ 14 - 0
test/unit/specs/utils.js

@@ -17,6 +17,12 @@ describe('Utils', function () {
             assert.strictEqual(utils.get(obj, 'a.b.c'), 123)
         })
 
+        it('should work on keypath with brackets', function () {
+            var obj = { a: { 'key-with-dash': { b: 123 } }}
+            assert.strictEqual(utils.get(obj, 'a["key-with-dash"].b'), 123)
+            assert.strictEqual(utils.get(obj, "a['key-with-dash'].b"), 123)
+        })
+
         it('should return undefined if path does not exist', function () {
             var obj = { a: {}}
             assert.strictEqual(utils.get(obj, 'a.b.c'), undefined)
@@ -32,6 +38,14 @@ describe('Utils', function () {
             assert.strictEqual(obj.a.b.c, 123)
         })
 
+        it('should work on keypath with brackets', function () {
+            var obj = { a: { 'key-with-dash': { b: 1 }}}
+            utils.set(obj, 'a["key-with-dash"].b', 2)
+            assert.strictEqual(obj.a['key-with-dash'].b, 2)
+            utils.set(obj, "a['key-with-dash'].b", 3)
+            assert.strictEqual(obj.a['key-with-dash'].b, 3)
+        })
+
         it('should set even if path does not exist', function () {
             var obj = {}
             utils.set(obj, 'a.b.c', 123)