为什么这个聚合物元素的 属性 解析为未定义?
Why does this polymer element's property resolve to undefined?
我正在尝试将属性动态分配给 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`
dom-module
的 categoryid
属性 不是 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>
我认为您 运行 在这里遇到了一系列问题,需要稍微重新考虑一下您的结构。
首先,因为 categoryid 属性绑定在您的元素之外,所以它的初始值将是未定义的。基本上,您的元素已创建并附加,所有生命周期方法 运行 和 then 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>
问题是您如何将 categoryid 传递到 products-service...这不是 products-service 元素本身的问题。如果你这样做 <products-service categoryid="5"></products-service>
它将起作用。显然您的应用程序要复杂得多,但我创建了一些可以正常工作的简单元素:
index.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>
产品-list.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>
产品-service.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>
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;
},
我正在尝试将属性动态分配给 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`
dom-module
的 categoryid
属性 不是 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>
我认为您 运行 在这里遇到了一系列问题,需要稍微重新考虑一下您的结构。
首先,因为 categoryid 属性绑定在您的元素之外,所以它的初始值将是未定义的。基本上,您的元素已创建并附加,所有生命周期方法 运行 和 then 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>
问题是您如何将 categoryid 传递到 products-service...这不是 products-service 元素本身的问题。如果你这样做 <products-service categoryid="5"></products-service>
它将起作用。显然您的应用程序要复杂得多,但我创建了一些可以正常工作的简单元素:
index.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>
产品-list.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>
产品-service.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>
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;
},