Browse Source

allow one-time interpolation inside all directives

Evan You 12 years ago
parent
commit
8cd19f0fdb
4 changed files with 45 additions and 11 deletions
  1. 8 6
      src/directive.js
  2. 6 5
      src/text-parser.js
  3. 16 0
      test/unit/specs/directive.js
  4. 15 0
      test/unit/specs/misc.js

+ 8 - 6
src/directive.js

@@ -3,7 +3,8 @@ var dirId           = 1,
     FILTER_TOKEN_RE = /[^\s'"]+|'[^']+'|"[^"]+"/g,
     NESTING_RE      = /^\$(parent|root)\./,
     SINGLE_VAR_RE   = /^[\w\.$]+$/,
-    QUOTE_RE        = /"/g
+    QUOTE_RE        = /"/g,
+    TextParser      = require('./text-parser')
 
 /**
  *  Directive class
@@ -38,11 +39,12 @@ function Directive (name, ast, definition, compiler, el) {
         return
     }
 
-    this.expression = (
-        this.isLiteral
-            ? compiler.eval(this.expression)
-            : this.expression
-    ).trim()
+    if (TextParser.Regex.test(this.key)) {
+        this.key = compiler.eval(this.key)
+        if (this.isLiteral) {
+            this.expression = this.key
+        }
+    }
 
     var filters = ast.filters,
         filter, fn, i, l, computed

+ 6 - 5
src/text-parser.js

@@ -1,10 +1,11 @@
 var openChar        = '{',
     endChar         = '}',
     ESCAPE_RE       = /[-.*+?^${}()|[\]\/\\]/g,
-    BINDING_RE      = buildInterpolationRegex(),
     // lazy require
     Directive
 
+exports.Regex = buildInterpolationRegex()
+
 function buildInterpolationRegex () {
     var open = escapeRegex(openChar),
         end  = escapeRegex(endChar)
@@ -16,10 +17,10 @@ function escapeRegex (str) {
 }
 
 function setDelimiters (delimiters) {
-    exports.delimiters = delimiters
     openChar = delimiters[0]
     endChar = delimiters[1]
-    BINDING_RE = buildInterpolationRegex()
+    exports.delimiters = delimiters
+    exports.Regex = buildInterpolationRegex()
 }
 
 /** 
@@ -30,10 +31,10 @@ function setDelimiters (delimiters) {
  *  3. object with key & html = true
  */
 function parse (text) {
-    if (!BINDING_RE.test(text)) return null
+    if (!exports.Regex.test(text)) return null
     var m, i, token, match, tokens = []
     /* jshint boss: true */
-    while (m = text.match(BINDING_RE)) {
+    while (m = text.match(exports.Regex)) {
         i = m.index
         if (i > 0) tokens.push(text.slice(0, i))
         token = { key: m[1].trim() }

+ 16 - 0
test/unit/specs/directive.js

@@ -13,6 +13,15 @@ describe('Directive', function () {
         }
     }
 
+    function makeSpy () {
+        var spy = function () {
+            spy.called++
+            spy.args = [].slice.call(arguments)
+        }
+        spy.called = 0
+        return spy
+    }
+
     function build (name, exp, compiler) {
         var ast = Directive.parse(exp)[0]
         return new Directive(name, ast, directives[name], compiler, {})
@@ -259,6 +268,13 @@ describe('Directive', function () {
             assert.strictEqual(f3.name, 'lowercase')
         })
 
+        it('should compile the key if the key contains interpolation tags', function () {
+            compiler.eval = makeSpy()
+            build('model', '{{abc}} | uppercase', compiler)
+            assert.ok(compiler.eval.called)
+            assert.equal(compiler.eval.args[0], '{{abc}}')
+        })
+
     })
 
     describe('.$applyFilters()', function () {

+ 15 - 0
test/unit/specs/misc.js

@@ -270,4 +270,19 @@ describe('Misc Features', function () {
 
     })
 
+    describe('interpolation in directive values', function () {
+        
+        it('should be evaled by the compiler', function () {
+            var t = new Vue({
+                template: '<input v-model="{{field}}">',
+                data: {
+                    field: 'test',
+                    test: 'hello'
+                }
+            })
+            assert.equal(t.$el.childNodes[0].value, 'hello')
+        })
+
+    })
+
 })