Pārlūkot izejas kodu

Remove regular attribute when null/undefined/false

Add test for removal on regular attr

add custom attribute test
Hugo 5 gadi atpakaļ
vecāks
revīzija
7d1df111b3
2 mainītis faili ar 30 papildinājumiem un 3 dzēšanām
  1. 8 3
      src/directives/bind.js
  2. 22 0
      test/bind.spec.js

+ 8 - 3
src/directives/bind.js

@@ -69,14 +69,19 @@ export function handleAttributeBindingDirective(component, el, attrName, express
             el.setAttribute('class', arrayUnique(originalClasses.concat(newClasses)).join(' '))
         }
     } else if (isBooleanAttr(attrName)) {
-        // Boolean attributes have to be explicitly added and removed, not just set.
-        if (!! value) {
+        if (!!value) {
             el.setAttribute(attrName, '')
         } else {
+            // If a Boolean attribute has a falsy value, remove the attribute
             el.removeAttribute(attrName)
         }
     } else {
-        el.setAttribute(attrName, value)
+        // If an attribute's bound value is null, undefined or false, remove the attribute
+        if ([null, undefined, false].includes(value)) {
+            el.removeAttribute(attrName)
+        } else {
+            el.setAttribute(attrName, value)
+        }
     }
 }
 

+ 22 - 0
test/bind.spec.js

@@ -175,6 +175,28 @@ test('class attribute bindings are synced by string syntax', async () => {
     expect(document.querySelector('span').classList.contains('baz')).toBeTruthy()
 })
 
+test('non-boolean attributes set to null/undefined/false are removed from the element', async () => {
+    document.body.innerHTML = `
+        <div x-data="{}">
+            <a href="#hello" x-bind:href="null"></a>
+            <a href="#hello" x-bind:href="false"></a>
+            <a href="#hello" x-bind:href="undefined"></a>
+            <!-- custom attribute see https://github.com/alpinejs/alpine/issues/280 -->
+            <span visible="true" x-bind:visible="null"></span>
+            <span visible="true" x-bind:visible="false"></span>
+            <span visible="true" x-bind:visible="undefined"></span>
+        </div>
+    `
+    Alpine.start()
+
+    expect(document.querySelectorAll('a')[0].getAttribute('href')).toBeNull()
+    expect(document.querySelectorAll('a')[1].getAttribute('href')).toBeNull()
+    expect(document.querySelectorAll('a')[2].getAttribute('href')).toBeNull()
+    expect(document.querySelectorAll('span')[0].getAttribute('visible')).toBeNull()
+    expect(document.querySelectorAll('span')[1].getAttribute('visible')).toBeNull()
+    expect(document.querySelectorAll('span')[2].getAttribute('visible')).toBeNull()
+})
+
 test('boolean attributes set to false are removed from element', async () => {
     document.body.innerHTML = `
         <div x-data="{ isSet: false }">