Почему свойство этого полимерного элемента становится неопределенным?

Я пытаюсь динамически назначить атрибут шаблону iron-ajax, но он разрешается как неопределенный.

<dom-module id="products-service">
  <style>
    :host {
      display: none;
    }
  </style>

  <template>
    <iron-ajax id="productsajax"
      auto
      url="http://localhost:3003/api/taxons/products"
      params='{"token":"my-token"}'
      method='GET'
      on-response='productsLoaded'
      handleAs='json'>
    </iron-ajax>
  </template>
</dom-module>

<script>
(function() {
    Polymer({
        is: 'products-service',

        properties: {
            categoryid: {
                type: String,
                notify: true,
                reflectToAttribute: true
            }
        },

        //here I am trying to add and `id` to the `iron-ajax` `params` attribute.
        ready: function() {
            this.$.productsajax.params.id = this.categoryid;
       }
    });
})();
</script>

Результирующий URL-адрес выглядит следующим образом:

`http://localhost:3003/api/taxons/products?token=my-token&id=undefined`

Свойство categoryid dom-module не является undefined, так как я вижу правильное значение свойства, отраженное в атрибутах, что означает, что это как-то связано с тем, как я назначаю его атрибуту. Я также пробовал это на обратных вызовах created и attached и все еще не работает.

Редактировать: categoryid передается модулю при его создании следующим образом:

<products-service products="{{products}}" categoryid="{{categoryid}}"></products-service>

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

введите здесь описание изображения

category-products-list, где вызывается служба, выглядит так

<dom-module id="category-products-list">
  <template>
    <category-products-service products="{{products}}" categoryid="{{categoryid}}"></category-products-service>
    <div>
      <template is="dom-repeat" items="{{products}}">
       <product-card on-cart-tap="handleCart" product="{{item}}">
         <img width="100" height="100">
         <h3>{{item.name}}</h3>
         <h4>{{item.display_price}}</h4>
       </product-card>
     </template>
  </div>
</template>

</dom-module>

<script>
 (function() {
  Polymer({
  is: 'category-products-list',

  properties: {
    categoryid: {
      type: String,
      notify: true,
      reflectToAttribute: true
    }
  },

ready: function() {
   //this is undefined too
   console.log("categoryid in the list module: "+categoryid)
   }
   });
   })();
</script>

person Optimus Pette    schedule 09.06.2015    source источник
comment
Откуда берется идентификатор категории? Где он установлен? Что происходит, когда вы добавляете console.log(this.categoryid); в вашей готовой функции?   -  person Erik Höhmann    schedule 09.06.2015
comment
Я отредактировал вопрос с информацией, которую вы ищете. Когда я делаю console.log(this.categoryid);: я получаю undefined   -  person Optimus Pette    schedule 09.06.2015
comment
проблема в том, как вы передаете идентификатор категории в продукты-услуги... это не проблема в самом элементе продуктов-услуг. Если вы выполните ‹products-service categoryid=5›‹/products-service›, это сработает. Итак, следующий вопрос: откуда вы берете идентификатор категории? Я не знаю, откуда вы берете {{categoryid}}, но я собираюсь предположить: вы можете попробовать ‹products-service products={{products}} categoryid$={{categoryid}}› ‹/продукты-услуги›   -  person Erik Höhmann    schedule 10.06.2015
comment
пожалуйста, проверьте мое последнее редактирование вопроса. categoryid, переданный службе, уже имеет значение.   -  person Optimus Pette    schedule 10.06.2015
comment
не могли бы вы также добавить свой элемент списка продуктов категории, пожалуйста. Я предполагаю, что основная проблема находится внутри этого элемента.   -  person Erik Höhmann    schedule 10.06.2015
comment
Значение, переданное через атрибут categoryid, должно быть доступно в ready, поэтому console.log не должно возвращать undefined. Пожалуйста, скопируйте и вставьте весь код для компонента как есть (за вычетом любых токенов безопасности), так как я подозреваю, что ответ заключается в опечатке или что-то в этом роде.   -  person Zikes    schedule 10.06.2015
comment
@ErikHöhmann, я добавил список dom-module. categoryid в этом модуле по адресу ready также является undefined, но он доступен, когда он присутствует при передаче службе dom-module.   -  person Optimus Pette    schedule 10.06.2015
comment
Спасибо. Я до сих пор не вижу, куда вы переходите в идентификаторе категории. Вероятно, вы передаете его в одном элементе выше. Я создал ответ, который работает. Может быть, вы можете использовать его в качестве ссылки. Вы также можете попробовать убрать свойство categoryid в скрипте category-products-service, так как похоже, что вы получаете его из родительского элемента.   -  person Erik Höhmann    schedule 10.06.2015
comment
CategoryId передается из маршрутов. page('/categories/:name/:categoryid', function (data) { app.route = 'category-page'; app.params = data.params; });   -  person Optimus Pette    schedule 10.06.2015


Ответы (3)


Я думаю, что вы столкнулись с рядом проблем, и вам нужно немного переосмыслить свою структуру.

Во-первых, поскольку атрибут categoryid привязан за пределами вашего элемента, его начальное значение будет неопределенным. По сути, ваш элемент создается и прикрепляется, выполняются все методы жизненного цикла, а затем устанавливается идентификатор категории. Это также означает, что, поскольку у вас есть набор iron-ajax с auto, он сначала попытается сделать запрос с информацией, которую ему предоставили в первую очередь.

Мои рекомендуемые изменения:

<dom-module id="products-service">
  <style>
    :host {
      display: none;
    }
  </style>

  <template>
    <iron-ajax id="productsajax"
      url="http://localhost:3003/api/taxons/products"
      params='{"token":"my-token"}'
      method='GET'
      on-response='productsLoaded'
      handleAs='json'>
    </iron-ajax>
  </template>
</dom-module>

<script>
(function() {
    Polymer({
        is: 'products-service',

        properties: {
            categoryid: {
                type: String,
                notify: true,
                reflectToAttribute: true
            }
        },

        observers: [
            // Note that this function  will not fire until *all* parameters
            // given have been set to something other than `undefined`
            'attributesReady(categoryid)'
        ],

        attributesReady: function(categoryid) {
            this.$.productsajax.params.id = categoryid;

            // With the removal of `auto` we must initiate the request
            // declaratively, but now we can be assured that all necessary
            // parameters have been set first.
            this.$.productsajax.generateRequest();
        }
    });
})();
</script>
person Zikes    schedule 09.06.2015
comment
Когда я это делаю, идентификатор не отражается в результирующем url, даже со значением undefined. - person Optimus Pette; 10.06.2015
comment
@OptimusPette Я подозреваю, что компонент iron-ajax не понимает, что его параметры были обновлены. Попробуйте this.$.productsajax.set('params.id', this.categoryid); - person Zikes; 10.06.2015
comment
тот же эффект, идентификатор не установлен в параметрах. - person Optimus Pette; 10.06.2015
comment
@OptimusPette, пожалуйста, взгляните на мой пересмотренный ответ - person Zikes; 10.06.2015
comment
Кажется, проблема была в этом все время. Теперь все работает нормально с вашими рекомендованными изменениями. Кажется, мне нужно пересмотреть документы по наблюдателям. - person Optimus Pette; 10.06.2015

проблема в том, как вы передаете идентификатор категории в продукты-услуги... это не проблема в самом элементе продуктов-услуг. Если вы сделаете <products-service categoryid="5"></products-service>, это сработает. Очевидно, что ваше приложение намного сложнее, но я создал несколько простых элементов, которые работают правильно:

индекс.html:

<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">

<title>My Test</title>

<!-- Load platform support before any code that touches the DOM. -->
<script src="bower_components/webcomponentsjs/webcomponents-lite.min.js">    </script>

<link rel="import" href="elements/product-list.html">

</head>

<body>
  <product-list categoryid="5"></product-list>
</body>

</html>

список продуктов.html:

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../elements/product-service.html">


<dom-module id="product-list">
<style>

</style>

<template>
<product-service categoryid="{{categoryid}}"></product-service>
</template>
</dom-module>

<script>
Polymer({
    is: 'product-list'
});
</script>

продукт-сервис.html:

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/iron-ajax/iron-ajax.html">


<dom-module id="product-service">
<style>

</style>

<template>
<iron-ajax id="productsajax"
  auto
  url="http://localhost:3003/api/taxons/products"
  params='{"token":"my-token"}'
  method='GET'
  on-response='productsLoaded'
  handleAs='json'>
</iron-ajax>
</template>
</dom-module>

<script>
Polymer({
    is: 'product-service',
    properties: {
      categoryid: {
              type: String,
              notify: true,
              reflectToAttribute: true
              }
},

//here I am trying to add and `id` to the `iron-ajax` `params` attribute.
ready: function() {
console.log(this.categoryid);
this.$.productsajax.params.id = this.categoryid;
},
productsLoaded: function(e) {
console.log('Response');
}

});
</script>
person Erik Höhmann    schedule 09.06.2015

Диагностика Zikes верна, причина, по которой возвращается неопределенное значение, заключается в том, что жизненный цикл страницы завершен до того, как данные будут загружены на страницу. Однако мне не удалось заставить его ответ работать для моего решения. (Возможно, где-то ошибка с моей стороны.) Мой API также использует строки запроса для передачи данных, в то время как ваш этого не делает, я считаю, что этот ответ будет полезен всем, кто сталкивается с такой ситуацией, как я. Чтобы решить эту проблему, я добавил наблюдателя к своему свойству, я взял этот ответ из https://www.polymer-project.org/1.0/docs/devguide/observers. Я использовал простой наблюдатель. Я считаю, что Zikes использует сложный.

<iron-ajax id="productsajax" url= {{ajaxUrl}} method='GET'
      on-response='productsLoaded' handleAs='json'>
</iron-ajax>

Polymer({
    is: 'product-service',
    properties: {
            categoryid: {
                type: String,
                notify: true,
                reflectToAttribute: true,
                observer: 'catIdReady'
            },
            ajaxUrl: {
                type: String,
                notify: true
            }
    },
    catIdReady: function (catidnew, catidold) {
        this.set('ajaxUrl', this._getAjaxUrl());
        this.$.productsajax.generateRequest();
        console.log("catidReady!" + catidnew);
    },
    _getAjaxUrl: function () {
        console.log(this.categoryid);
        return 'http://localhost:3003/api/taxons/products?categoryId=' + 
        this.categoryid;
    },

person Patrick Knott    schedule 10.05.2017