2016-05-16 11 views
4

Я изучаю пользовательские элементы HTML-компонентов веб-компонентов, и у меня возникает проблема с добавлением пользовательских атрибутов к моим пользовательским элементам: любое значение, установленное в разметке, никогда не выполняется. Для простого элемента, подобного этому, который должен показывать текст, указанный в атрибуте «flagtext», он всегда показывает значение по умолчанию.Пользовательский атрибут HTML-элемента не отображается - Веб-компоненты

<test-flag flagtext="my text"></test-flag> 

Полный JSBin образец here.

JSBin использует библиотеку Polymer (так как это единственное, что я могу там потянуть). Я использую webcomponents.js, как правило, тот же результат. И в Chrome 49, и в Firefox 45 дает тот же результат. В консоли или отладчике нет ошибок.

Каждый образец, который я нахожу в Интернете, имеет похожий код, но я пробовал различные версии и всегда отказывается обновлять. Я даже скопировал несколько образцов в JSBin, и они тоже не работают.

Что может быть неправильным? Я понимаю, что это экспериментальная технология, но последовательность, с которой это не работает, все еще удивляет. Отказался ли этот стандарт? (Я вижу, что последний проект пользовательских элементов в апреле 2016 года W3C полностью изменил его подход.)

Когда я определяю функцию attributeChangedCallback, он не срабатывает. Я могу легко изменить свойство с помощью Javascript, это не проблема.

Но почему я не могу указать свойство в разметке, как я должен?

Edit - полный код

Обратите внимание, что вам необходимо поместить их в отдельные файлы HTML для импорта, и что вам нужно «веб-компоненты-lite.js» библиотека.

Основной HTML файл

<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <style> 
     test-flag 
     { 
      border: 1px solid blue; 
     } 
    </style> 
</head> 
<body> 
    <script src="lib/webcomponents-lite.min.js"></script> 
    <link rel="import" href="test-flag.html"> 

    Here is the custom test-flag component: 
    <p>  
    <test-flag flagtext="my text"></test-flag> 
</body> 
</html> 

Файл: тест-flag.html

<template> 

    <style> 
    </style> 

    Content: 
    <div id="testflagID"> 
    </div> 

</template> 


<script>  

    (function() { 

     var _currentScript = (document._currentScript || document.currentScript); 
     var importDoc = _currentScript.ownerDocument; 
     var customPrototype = Object.create(HTMLElement.prototype);   
     Object.defineProperty(customPrototype, 'flagtext', {value: '(default)', writable: true});  
     document.registerElement('test-flag', {prototype: customPrototype}); 


     customPrototype.createdCallback = function() 
     { 
      var template = importDoc.querySelector('template'); 
      var clone = document.importNode(template.content, true); 
      var idx = clone.querySelector("#testflagID"); 
      idx.textContent = this.flagtext; 
      var root = this; 
      var createdElement = root.appendChild(clone); 

     }; 

    })(); 

</script> 
+1

WebComponents - это только Chrome. Он не работает во всех браузерах, кроме Chrome и Opera (опера имеет тот же движок, что и хром). http://caniuse.com/#search=components. Избегайте использовать его –

+1

(a) Это неверно - полиполк webcomponents.js обеспечивает функциональность во многих браузерах, и в моих тестах многое из этого работает, но не это, (б), как упоминалось выше, образец isn ' t, работающий в Chrome, либо – nepdev

+0

'позволяет функциям ошибиться. Эмулирует поведение, но это не веб-компоненты. Тем не менее, я не могу получить доступ к jsbin.com из своей работы, потому что лучше, чтобы вы делили код ** в самом вопросе ** (поскольку [справочный центр] (http://stackoverflow.com/help) сказал). –

ответ

7

Есть 2 понятия, которые автоматически не связаны друг с другом.

В HTML-код:

<test-flag flagtext="my text"></test-flag> 

... Термин flagtextявляется атрибутом HTML (не свойство).

В коде JavaScript:

Object.defineProperty(customPrototype, 'flagtext', {value: '(default)', writable: true}) 

... Термин flagtextявляется свойством JavaScript (не атрибут).

Для стандартных элементов, браузер автоматически связывает значение собственности на атрибут значение (и наоборот).Для пользовательских элементов тоже (со стандартными атрибутами). Но если вы хотите добавить атрибут , вам придется привязать его вручную.

Например, в методе createdCallback(), добавьте:

this.flagtext = this.getAttribute('flagtext') || '(default)' 

Живой пример:

document.registerElement('test-flag' , { 
 
    prototype: Object.create(HTMLElement.prototype, { 
 
    flagtext: { 
 
     value: '(default)', 
 
     writable: true 
 
    }, 
 
    createdCallback: { 
 
     value: function() 
 
     { 
 
     this.flagtext = this.getAttribute('flagtext') || this.flagtext 
 
     this.innerHTML = 'flagtext=' + this.flagtext 
 
     } 
 
    }, 
 
    }) 
 
})
<test-flag flagtext='new content'>Hello</test-flag>

NB: метод attributeChangedCallback() запускается только при изменении атрибута после создания (что здесь не так).

+0

Отлично - это работает! – nepdev

+0

@Supersharp Мне жаль, что я не нашел это месяц назад. Я искал свой b ... о том, как связаны свойства и атрибуты, и почему я был в некоторых случаях связанными, а в некоторых случаях и не был. Я бы хотел, чтобы это стало более понятным всем этим блогам и сайтам, продвигающим веб-компоненты. Удивительный, хотя я приехал довольно поздно. Большое спасибо – LongHike