запуск событий полимера 1.0 среди вложенных компонентов

У меня есть проблема в Polymer 1.0, связанная с распространением событий во вложенной структуре веб-компонентов. В частности, я пытаюсь динамически настроить веб-компонент с именем wc-split с помощью набора других компонентов с именем wc-split-rule, расположенных в его локальной модели DOM. Следующий фрагмент кода показывает правильную форму использования:

<wc-split-test>
    <wc-split>
        <wc-split-rule key="{{k1}}" ...></wc-split-rule>
        <wc-split-rule key="{{k2}}" ...></wc-split-rule>
        <wc-split-rule key="{{k3}}" ...></wc-split-rule>
   </wc-split> 
</wc-split-test>

Как видно из предыдущего примера, цель состоит в том, чтобы предоставить компоненту wc-split значения атрибутов key в каждом компоненте wc-split-rule. Поскольку нам нужны возможности динамической реконфигурации, архитектурная стратегия начинается с запуска события каждый раз, когда встречается изменение атрибутов key, и эти изменения продвигаются путем всплытия, чтобы достичь компонента wc-split, который их обрабатывает.

Следующий подход работает должным образом, когда [1] он тестируется как в чистом HTML-контексте с литеральными значениями, так и [2] в шаблоне компонента со значениями, привязанными к данным. Тем не менее, [3] когда он тестируется в шаблоне компонента с использованием литеральных значений, изменения не продвигаются. Кажется, что распространение события игнорируется или прослушиватель, определенный в wc-split, не перехватывает событие:

<wc-split-test>
    <wc-split> <!-- does not work -->
        <wc-split-rule key="k1" ...></wc-split-rule>
        <wc-split-rule key="k2" ...></wc-split-rule>
        <wc-split-rule key="k3" ...></wc-split-rule>
    </wc-split>
</wc-split-test>

В следующем листинге показана реализация обоих компонентов [https://goo.gl/OkU9jQ]:

    <dom-module id="wc-split-rule">
        <script>                
            Polymer({
                is: 'wc-split-rule',  

                properties: {
                    key  : {
                        type: String,
                        reflectToAttribute: true,
                        notify: true,
                        value: '',
                        observer: '_changed'
                    },
                }, 

                _changed: function (){
                    this.fire('wc-split-rule', {
                        key     : this.key,
                    });                        
                }    

            });
        </script>
    </dom-module>


    <dom-module id="wc-split">   
        <template>
           <content></content>         
        </template>

        <script>     
            Polymer( { 
                is: 'wc-split', 

                listeners: {
                    'wc-split-rule': 'onRule'
                },

                ready: function(){
                   ...
                },

                onRule: function (event, context){
                    ... // this is executed in test [1] and [2] NOT in [3]                        
                }
            });     
        </script>

    </dom-module>


    <dom-module id="wc-split-test">          
        <template>              
            <wc-split id="split">
                <wc-split-rule key="e1"/>                        
            </wc-split>            
        </template>

        <script>     
            ...
        </script>

    </dom-module>

Удивительно, но один и тот же код на Polymer 0.5 корректно работает для каждого тестового сценария [https://goo.gl/CHV3JE]:

    <polymer-element name="wc-split-rule">  
        <script>

            Polymer('wc-split-rule', {
                publish : {
                    key     : '',                       
                },

                observe: {
                    key     : '_changed',                       
                },

                _changed: function (){
                    this.fire('wc-split-rule', {
                        key     : this.key,
                    });                        
                }    

            });
        </script>
    </polymer-element>


    <polymer-element name="wc-split">
        <template>
            <div on-wc-split-rule="{{onRule}}">
                <content select="wc-split-rule"></content>
            </div>
            <content></content>        
        </template>
        <script>

            Polymer('wc-split', {                    

                ready: function(){
                    ...
                },                   

                onRule: function (event, context){
                    ... // this is always executed
                }
            });     
        </script>

    </polymer-element>


     <polymer-element name="wc-split-test">
        <template>              
            <wc-split id="split">
                <wc-split-rule key="e1"/>                        
            </wc-split>            
        </template>

        <script>
            ...
        </script>

    </polymer-element>       

person Oscar Jiménez    schedule 19.08.2015    source источник
comment
Запустив ваш образец, кажется, что родитель получает событие. Можете ли вы прояснить проблему? Что вы ожидаете от образца 1.0, чего он не делает сейчас?   -  person DocDude    schedule 19.08.2015
comment
Спасибо DocDude за помощь. Я переписал вопрос. Пожалуйста, не могли бы вы взглянуть на него?   -  person Oscar Jiménez    schedule 24.08.2015


Ответы (1)


Это сводится к проблеме времени. Событие wc-split-rule запускается до регистрации вашего элемента wc-split. Поэтому событие упускается. Это проблема только тогда, когда элементы загружаются впервые, потому что у вас есть родительский элемент, который также является пользовательским элементом. Один из способов обойти это — убедиться, что событие срабатывает после присоединения wc-split-rule:

attached: function() {
  this._changed();
},

Это работает: http://jsbin.com/yixinuhahu/edit?html,output

person ebidel    schedule 24.08.2015