Kaynağa Gözat

add objects support to v-attr

Евгений 11 yıl önce
ebeveyn
işleme
93837c2310
2 değiştirilmiş dosya ile 65 ekleme ve 37 silme
  1. 36 20
      src/directives/attr.js
  2. 29 17
      test/unit/specs/directives/attr_spec.js

+ 36 - 20
src/directives/attr.js

@@ -6,27 +6,43 @@ module.exports = {
 
   priority: 850,
 
-  bind: function () {
-    var name = this.arg
-    this.update = xlinkRE.test(name)
-      ? xlinkHandler
-      : defaultHandler
-  }
+  update: function (value) {
+    if (this.arg) {
+      this.setAttr(this.arg, value)
+    } else if (typeof value === 'object') {
+      this.objectHandler(value)
+    }
+  },
 
-}
+  objectHandler: function (value) {
+    // cache object attrs so that only changed attrs
+    // are actually updated.
+    var cache = this.cache || (this.cache = {})
+    var attr, val
+    for (attr in cache) {
+      if (!(attr in value))
+        this.setAttr(attr, null)
+        delete cache[attr]
+    }
+    for (attr in value) {
+      val = value[attr]
+      if (val !== cache[attr]) {
+        cache[attr] = val
+        this.setAttr(attr, val)
+      }
+    }
+  },
 
-function defaultHandler (value) {
-  if (value || value === 0) {
-    this.el.setAttribute(this.arg, value)
-  } else {
-    this.el.removeAttribute(this.arg)
+  setAttr: function (attr, value) {
+    if (value || value === 0) {
+      if (xlinkRE.test(attr)) {
+        this.el.setAttributeNS(xlinkNS, attr, value)
+      } else {
+        this.el.setAttribute(attr, value)
+      }
+    } else {
+      this.el.removeAttribute(attr)
+    }
   }
-}
 
-function xlinkHandler (value) {
-  if (value != null) {
-    this.el.setAttributeNS(xlinkNS, this.arg, value)
-  } else {
-    this.el.removeAttributeNS(xlinkNS, 'href')
-  }
-}
+}

+ 29 - 17
test/unit/specs/directives/attr_spec.js

@@ -4,18 +4,16 @@ var def = require('../../../../src/directives/attr')
 if (_.inBrowser) {
   describe('v-attr', function () {
 
-    var el
+    var el, dir
     beforeEach(function () {
       el = document.createElement('div')
+      dir = {el:el}
+      _.extend(dir, def)
     })
 
     it('normal attr', function () {
-      var dir = {
-        el: el,
-        arg: 'test'
-      }
-      _.extend(dir, def)
-      dir.bind()
+      dir.arg = 'test'
+
       dir.update('ok')
       expect(el.getAttribute('test')).toBe('ok')
       dir.update('again')
@@ -30,19 +28,33 @@ if (_.inBrowser) {
 
     it('xlink', function () {
       var xlinkNS = 'http://www.w3.org/1999/xlink'
-      var dir = {
-        el: el,
-        arg: 'xlink:href'
-      }
-      _.extend(dir, def)
-      dir.bind()
+      dir.arg = 'xlink:special'
+
       dir.update('ok')
-      expect(el.getAttributeNS(xlinkNS, 'href')).toBe('ok')
+      expect(el.getAttributeNS(xlinkNS, 'special')).toBe('ok')
       dir.update('again')
-      expect(el.getAttributeNS(xlinkNS, 'href')).toBe('again')
+      expect(el.getAttributeNS(xlinkNS, 'special')).toBe('again')
       dir.update(null)
-      expect(el.hasAttributeNS(xlinkNS, 'test')).toBe(false)
+      expect(el.hasAttributeNS(xlinkNS, 'special')).toBe(false)
     })
 
+    it('object and xlink', function () {
+      var xlinkNS = 'http://www.w3.org/1999/xlink'
+      var obj1 = {special:'ok', test:'again'}
+      var obj2 = {'xlink:href': '#', test: 'ok', empty:null}
+      dir.update(obj2)
+      expect(el.getAttributeNS(xlinkNS, 'href')).toBe('#')
+      expect(el.getAttribute('test')).toBe('ok')
+      expect(el.hasAttribute('empty')).toBe(false)
+      dir.update(obj1)
+      expect(el.hasAttributeNS(xlinkNS, 'href')).toBe(false)
+      expect(el.getAttribute('special')).toBe('ok')
+      expect(el.getAttribute('test')).toBe('again')
+      obj1.test = null
+      dir.update(obj1)
+      expect(el.hasAttribute('test')).toBe(false)
+      dir.update(obj2)
+      expect(el.getAttributeNS(xlinkNS, 'href')).toBe('#')
+    })
   })
-}
+}