Browse Source

fix exp-parser so it correctly access variables that start with $ in expressions

Evan You 12 years ago
parent
commit
92dd92a0d7
3 changed files with 34 additions and 9 deletions
  1. 6 4
      src/compiler.js
  2. 1 1
      src/directives/repeat.js
  3. 27 4
      src/exp-parser.js

+ 6 - 4
src/compiler.js

@@ -413,10 +413,12 @@ CompilerProto.bindDirective = function (directive) {
     }
 
     // set initial value
-    if (binding.isComputed) {
-        directive.refresh(value)
-    } else {
-        directive.update(value, true)
+    if (value !== undefined) {
+        if (binding.isComputed) {
+            directive.refresh(value)
+        } else {
+            directive.update(value, true)
+        }
     }
 }
 

+ 1 - 1
src/directives/repeat.js

@@ -130,7 +130,7 @@ module.exports = {
             this.buildItem()
             this.initiated = true
         }
-        this.collection = collection || []
+        collection = this.collection = collection || []
         this.vms = []
 
         // listen for collection mutation events

+ 27 - 4
src/exp-parser.js

@@ -68,7 +68,10 @@ function getRel (path, compiler) {
         }
     }
     compiler = vm.$compiler
-    if (!hasOwn.call(compiler.bindings, path)) {
+    if (
+        !hasOwn.call(compiler.bindings, path) &&
+        path.charAt(0) !== '$'
+    ) {
         compiler.createBinding(path)
     }
     return rel
@@ -90,6 +93,15 @@ function makeGetter (exp, raw) {
     return fn
 }
 
+/**
+ *  Escape a leading dollar sign for regex construction
+ */
+function escapeDollar (v) {
+    return v.charAt(0) === '$'
+        ? '\\' + v
+        : v
+}
+
 module.exports = {
 
     /**
@@ -105,11 +117,22 @@ module.exports = {
         }
         vars = utils.unique(vars)
         var accessors = '',
-            pathRE = new RegExp("\\b(" + vars.join('|') + ")[$\\w\\.]*\\b", 'g'),
-            body = 'return ' + exp.replace(pathRE, function (path) {
+            // construct a regex to extract all valid variable paths
+            // ones that begin with "$" are particularly tricky
+            // because we can't use \b for them
+            pathRE = new RegExp(
+                "[^$\\w\\.](" +
+                vars.map(escapeDollar).join('|') +
+                ")[$\\w\\.]*\\b", 'g'
+            ),
+            body = ('return ' + exp).replace(pathRE, function (path) {
+                // keep track of the first char
+                var c = path.charAt(0)
+                path = path.slice(1)
                 var val = 'this.' + getRel(path, compiler) + path
                 accessors += val + ';'
-                return val
+                // don't forget to put that first char back
+                return c + val
             })
         body = accessors + body
         return makeGetter(body, exp)