2
0
Эх сурвалжийг харах

allow multiple tags in attribute bindings

Evan You 11 жил өмнө
parent
commit
6bdeb6ddea

+ 24 - 19
src/compile/compile.js

@@ -116,12 +116,9 @@ function makeDirectivesLinkFn (directives) {
     var dir, j
     while (i--) {
       dir = directives[i]
-      if (dir.oneTime) {
-        // one time attr interpolation
-        el.setAttribute(
-          dir.name,
-          vm.$eval(dir.value)
-        )
+      if (dir._link) {
+        // custom link fn
+        dir._link(vm, el)
       } else {
         j = dir.descriptors.length
         while (j--) {
@@ -465,21 +462,29 @@ function collectDirectives (el, options) {
 function collectAttrDirective (el, name, value, options) {
   var tokens = textParser.parse(value)
   if (tokens) {
-    if (tokens.length === 1 && tokens[0].oneTime) {
-      return {
-        name: name,
-        value: tokens[0].value,
-        def: options.directives.attr,
-        oneTime: true
-      }
-    } else {
-      value = textParser.tokensToExp(tokens)
-      return {
-        name: 'attr',
-        def: options.directives.attr,
-        descriptors: dirParser.parse(name + ':' + value)
+    var def = options.directives.attr
+    var i = tokens.length
+    var allOneTime = true
+    while (i--) {
+      var token = tokens[i]
+      if (token.tag && !token.oneTime) {
+        allOneTime = false
       }
     }
+    return {
+      def: def,
+      _link: allOneTime
+        ? function (vm, el) {
+            el.setAttribute(name, vm.$interpolate(value))
+          }
+        : function (vm, el) {
+            var value = textParser.tokensToExp(tokens, vm)
+            var desc = dirParser.parse(name + ':' + value)[0]
+            vm._directives.push(
+              new Direcitve('attr', el, vm, desc, def)
+            )
+          }
+    }
   }
 }
 

+ 18 - 5
src/parse/text.js

@@ -108,17 +108,30 @@ exports.parse = function (text) {
  * Format a list of tokens into an expression.
  *
  * @param {Array} tokens
+ * @param {Vue} [vm]
  * @return {String}
  */
 
-exports.tokensToExp = function (tokens) {
+exports.tokensToExp = function (tokens, vm) {
   return tokens.length > 1
-    ? tokens.map(formatToken).join('+')
-    : formatToken(tokens[0])
+    ? tokens.map(function (token) {
+      return formatToken(token, vm)
+    }).join('+')
+    : formatToken(tokens[0], vm)
 }
 
-function formatToken (token) {
+/**
+ * Format a single token.
+ *
+ * @param {Object} token
+ * @param {Vue} [vm]
+ * @return {String}
+ */
+
+function formatToken (token, vm) {
   return token.tag
-    ? token.value
+    ? token.oneTime
+      ? '"' + vm.$get(token.value) + '"'
+      : token.value
     : '"' + token.value + '"'
 }

+ 10 - 0
test/unit/specs/parse/text_spec.js

@@ -1,5 +1,6 @@
 var textParser = require('../../../../src/parse/text')
 var config = require('../../../../src/config')
+var Vue = require('../../../../src/vue')
 
 var testCases = [
   {
@@ -92,4 +93,13 @@ describe('Text Parser', function () {
     expect(exp).toBe('"view-"+test+"-test-"+ok')
   })
 
+  it('tokens to expression with oneTime tags & vm', function () {
+    var vm = new Vue({
+      data: { test: 'a', ok: 'b' }
+    })
+    var tokens = textParser.parse('view-{{*test}}-test-{{ok}}')
+    var exp = textParser.tokensToExp(tokens, vm)
+    expect(exp).toBe('"view-"+"a"+"-test-"+ok')
+  })
+
 })