2014-07-01 2 views
2

Я пытаюсь использовать requirejs с полимером:Polymer + requirejs: Атрибуты были данные, связанным до Polymer обновляющегося элемента

<polymer-element name="test-element"> 
    <script> 
    require(['module'], function (module) { 
     Polymer('test-element', module); 
    }); 
    </script> 
    <template> 
    Test 
    </template> 
</polymer-element> 

Но я получаю предупреждение:

Attributes on test-element were data bound prior to Polymer upgrading the element. This may result in incorrect binding types. 
  1. Должен ли я быть обеспокоен этим предупреждением?
  2. Что я могу сделать, чтобы сделать атрибуты связанными данными после того, как Polymer обновит элемент?
  3. Is Есть ли какой-либо другой полимерный загрузчик для загрузки модулей AMD в полимерные веб-компоненты?

--------- редактировать
Оказался, что эта проблема возникает только тогда, когда тест-элемент находится внутри anouther полимера веб-компоненты. Я создал GitHub репо, чтобы показать это: https://github.com/finalclass/polymer-bug-requirejs

ответ

3

EDIT: Спасибо за разъяснение, что это только вопрос, когда ваш полимерный элемент находится внутри другого элемента Polymer. Это указывает на основную проблему. Не обязательно использовать requirejs; Вы можете воспроизвести предупреждение через что-то вроде

<script> 
    setTimeout(function() { 
    Polymer('test-b', {}); 
    }, 0); 
</script> 

В обоих случаях функция Polymer('test-b', ...) вызывается асинхронно после родительского элемента (<test-a> в вашем примере) уже полностью инициализирован, и это, очевидно, не является хорошей практикой.

Вы можете реорганизовать вещи немного, чтобы добраться до того, что Полимер доволен. Например, если module имеет кучу свойств, которые вы хотите установить на вашем <test-b>, вы можете отложить загрузку модуля и не устанавливать их, пока после того, как created обратный вызов был уволен, как так:

<script> 
    Polymer('test-b', { 
    created: function() { 
     var testB = this; 
     require(['test-b-js'], function (module) { 
     // There might be a more efficient way to copy over the properties... 
     Object.keys(module).forEach(function(key) { 
      testB.publish[key] = module[key]; 
     }); 
     }); 
    } 
    }); 
</script> 

Это следует documented best practice для инициализации свойств, которые являются массивом/объектами, без необходимости беспокоиться о распространенных состояниях, поэтому есть дополнительное преимущество. Существует небольшая озабоченность тем, что свойства фактически не будут установлены во время обратного вызова created, но вместо этого немного позже (поскольку снова обратный вызов в require() является асинхронным), но на практике это может и не быть проблемой.

Потенциально большая проблема заключается в том, что эти свойства не будут published; если это важно для вас, то требуется более креативное решение.

+0

Спасибо за разъяснение. К сожалению, это не ответ на мои вопросы :( –

1

Обсуждение в ответе Джеффа прямо на деньги. Как только вы отложите регистрацию какого-либо элемента каким-либо образом (например, setTimeout, require), вы должны убедиться, что никто еще не пытается использовать элемент до его готовности.

Другая возможность состоит в том, чтобы только отложить доступ к коду модуля, а не блокировать элемент целиком, что-то вроде этого:

<script> 
(function() { 

    var base = null; 
    require(['base'], function(module) { 
    base = module; 
    }); 

    Polymer({ 
    get name() { 
     return base ? null : base.name; 
    } 
    }); 

})(); 
</script>