[英]Polymer v1.3.1 databind not working with or without iron-ajax with repeat template and json array
Display html table from json array of objects via Polymer. 通过Polymer显示对象的json数组中的html表。
Fails to bind json data with message: Polymer::Attributes: couldn`t decode Array as JSON 无法通过消息绑定JSON数据: Polymer :: Attributes:无法将数组解码为JSON
The same message above is logged using iron-ajax or using ajax directly, the results of this test is using ajax directly to bypass possible issues with iron-ajax. 使用iron-ajax或直接使用ajax记录上面相同的消息,此测试的结果是直接使用ajax来绕过iron-ajax的可能问题。 The problem is binding the json returned from the webservice to the Polymer repeater. 问题是将从Web服务返回的json绑定到Polymer转发器。
<polymer-element name="fixtures-list">
<!-- <iron-ajax auto id="matchesService" verbose="true"
params='{{ajaxParams}}'
url="http://localhost:20440/MatchesService.svc/matches/GetAllForTeamInSeason"
handle-as="json"
method="GET"
on-request="handleRequestSent"
on-response="handleResponseReceived"
on-error="handleError"
last-response="{{matches}}"
debounce-duration="300"></iron-ajax>-->
<table class="table table-responsive">
<thead>
<tr>
<th>Date</th>
<th><abbr title="Kick Off">KO</abbr>/Result</th>
<th></th>
<th>Opponent</th>
<th>Venue</th>
<th><abbr title="Competition">Comp</abbr></th>
<th><abbr title="Televised">TV</abbr>/<abbr title="Attendance">ATT</abbr></th>
</tr>
</thead>
<tbody>
<template is="dom-repeat" items="{{matches}}">
<tr>
<td>{{KickOff}}</td>
<td>
<template if="{{IsResult}}">
{{Result}}
</template>
<template if="{{!IsResult}}">
{{KickOff}}
</template>
</td>
<td>{{Result}}</td>
<td>{{OpponentNameShort}}</td>
<td>{{Venue}}</td>
<td>{{EventAbbreviations}}</td>
<td>
<template if="{{IsResult}}">
{{Attendance}}
</template>
<template if="{{!IsResult}}">
{{BroadcasterAbbreviations}}
</template>
</td>
</tr>
</template>
</tbody>
</table>
<script>
Polymer({
is: 'fixtures-list',
properties: {
siteid: {
type: Number,
value: -1,
notify: true,
reflectToAttribute: true,
observer: 'logChange'
},
teamid: {
type: Number,
value: -1,
notify: true,
reflectToAttribute: true,
observer: 'logChange'
},
seasonid: {
type: Number,
value: -1,
notify: true,
reflectToAttribute: true,
observer: 'logChange'
},
ajaxParams: {
type: Object,
computed: 'processParams(siteid, teamid, seasonid)'
}
},
matches: [],
ready: function () {
console.log('polymer element ready');
$.ajax({
url: 'http://localhost:20440/MatchesService.svc/matches/GetAllForTeamInSeason',
data: {
siteId: this.siteid,
teamId: this.teamid,
seasonId: this.seasonid
},
error: function () {
console.log('ajax error');
},
dataType: 'json',
success: function (data) {
//console.log(JSON.parse(data));
this.matches = data;
},
type: 'GET'
});
},
processParams: function(siteid, teamid, seasonid) {
console.log('processParams: ' + siteid + ', ' + teamid + ', ' + seasonid);
return {
siteId: siteid,
teamId: teamid,
seasonId: seasonid
}
},
logChange: function(newValue, oldValue) {
console.log('Param changed to: ', newValue);
},
handleRequestSent: function (request) {
console.log('ReqSent');
//console.log(request);
},
handleResponseReceived: function (response) {
console.log('ResReceived');
//console.log(response);
//console.log("Received response: " + JSON.stringify(response.detail.response));
//this.result = response.detail.response;
},
handleError: function (event) {
console.log('error');
//var request = event.detail.request;
//var error = event.detail.error;
//console.log(request);
//console.log(error);
}
});
</script>
</polymer-element>
The Polymer::Attributes: couldn`t decode Array as JSON message is returned from the following function, I've added console logs for each statement and commented out setting the value to null within the try/catch for a type of array JSON.parse for more details. Polymer :: Attributes:无法解码数组,因为从以下函数返回JSON消息,我为每个语句添加了控制台日志,并注释掉了try / catch中将值设置为null的类型的数组JSON。解析更多细节。
At first i thought the process was double JSON decoding so i set the ajax dataType to 'text' and tried parsing the data manually with JSON.parse and the data parsed successfully. 起初我认为这个过程是双JSON解码所以我将ajax dataType设置为'text'并尝试使用JSON.parse手动解析数据并成功解析数据。
deserialize: function (value, type) {
switch (type) {
case Number:
console.log('Number: ' + value);
value = Number(value);
break;
case Boolean:
console.log('Boolean: ' + value);
value = value != null;
break;
case Object:
console.log('Object: ' + value);
try {
value = JSON.parse(value);
} catch (x) {
}
break;
case Array:
console.log('Array: ' + value);
try {
value = JSON.parse(value);
} catch (x) {
//value = null;
console.warn('Polymer::Attributes: couldn`t decode Array as JSON');
}
break;
case Date:
console.log('Date: ' + value);
value = new Date(value);
break;
case String:
console.log('String: ' + value);
default:
break;
}
return value;
}
Firebug Console Logs Firebug控制台日志
JSON returned from web service JSON从Web服务返回
It feels as if Polymer is getting {{matches}} as a string and not the actual data, if anyone could shed some light on this relatively new technology i'd be very grateful - thank you. 感觉好像Polymer将{{matches}}作为字符串而不是实际数据,如果有人能够对这种相对较新的技术有所了解,我将非常感激 - 谢谢。
Hi I found the answer the first line starts with a polymer-element tag which is used for an older version of polymer, the new version uses dom-module. 嗨,我发现答案第一行以聚合物元素标签开头,用于旧版聚合物,新版本使用dom-module。
Also added observers to ensure all variables are set before getting data via ajax. 还添加了观察者以确保在通过ajax获取数据之前设置所有变量。
Here's a working version: 这是一个工作版本:
<dom-module id="fixtures-list">
<template>
<row>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12">
<select id="fixtures-list-season-selector" class="selectpicker"></select>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 text-right">
<span class="label label-info">home match</span>
</div>
</row>
<table class="table table-responsive">
<thead>
<tr>
<th>Date</th>
<th class="text-center">
<span class="hidden-xs"><abbr title="Kick Off">KO</abbr>/Result</span>
<span class="visible-xs"><abbr title="Kick Off">KO</abbr>/<abbr title="Result">Res</abbr></span>
</th>
<th></th>
<th>Opponent</th>
<th class="hidden-xs">Venue</th>
<th class="hidden-xs" class="text-center"><abbr title="Competition">Comp</abbr></th>
<th class="hidden-xs" class="text-center"><abbr title="Televised">TV</abbr>/<abbr title="Attendance">ATT</abbr></th>
<th></th>
</tr>
</thead>
<tbody>
<template is="dom-repeat" items="{{fixturesData}}" as="fixture">
<tr class$="{{highlightRow(fixture.IsHome)}}">
<td>
<span class="hidden-xs">{{displayDate(fixture.KickOff)}}</span>
<span class="visible-xs">{{displayShortDate(fixture.KickOff)}}</span>
</td>
<td class="text-center">
<template is="dom-if" if="{{fixture.IsResult}}">
{{fixture.Score}}
</template>
<template is="dom-if" if="{{!fixture.IsResult}}">
{{displayTime(fixture.KickOff)}}
</template>
</td>
<td>
<template is="dom-if" if="{{fixture.IsResult}}">
{{fixture.Result}}
</template>
</td>
<td>{{fixture.OpponentNameShort}}</td>
<td class="hidden-xs">{{fixture.Venue}}</td>
<td class="text-center hidden-xs">{{fixture.EventAbbreviations}}</td>
<td class="text-center hidden-xs">
<template is="dom-if" if="{{fixture.IsResult}}">
{{fixture.Attendance}}
</template>
<template is="dom-if" if="{{!fixture.IsResult}}">
{{fixture.BroadcasterAbbreviations}}
</template>
</td>
<td class="text-center">
<template is="dom-if" if="{{fixture.IsResult}}">
<a href="/MatchReport/{{fixture.Id}}/" class="btn btn-default">view</a>
</template>
<template is="dom-if" if="{{!fixture.IsResult}}">
<a href="/MatchPreview/{{fixture.Id}}/" class="btn btn-default">view</a>
</template>
</td>
</tr>
</template>
</tbody>
</table>
</template>
<script>
Polymer({
is: 'fixtures-list',
properties: {
siteid: {
type: Number,
value: -1,
notify: true,
reflectToAttribute: true,
observer: 'logChange'
},
teamid: {
type: Number,
value: -1,
notify: true,
reflectToAttribute: true,
observer: 'logChange'
},
dateformatstring: {
type: String,
value: '',
notify: true,
reflectToAttribute: true,
observer: 'logChange'
},
timeformatstring: {
type: String,
value: '',
notify: true,
reflectToAttribute: true,
observer: 'logChange'
},
seasonstarted: {
type: String,
value: '',
notify: true,
reflectToAttribute: true,
observer: 'logChange'
},
ajaxParams: {
type: Object,
computed: 'processParams(siteid, teamid, seasonid)'
},
fixturesData: {
type: Array,
value: function () { return []; }
}
},
isAttributeValuesReady: false,
observers: [
// Note that this function will not fire until *all* parameters given have been set to something other than `undefined`
'attributesReady(siteid, teamid, dateformatstring, timeformatstring)'
],
attributesReady: function (siteid, teamid, dateformatstring, timeformatstring) {
this.isAttributeValuesReady = true;
console.log('attributesReady: ' + siteid + ', ' + teamid + ', ' + dateformatstring + ', ' + timeformatstring);
//this.$.matchesService.set('params.siteId', siteid);
//this.$.matchesService.set('params.teamId', teamid);
//this.$.matchesService.set('params.dateFormatString', dateFormatString);
//this.$.matchesService.set('params.timeFormatString', timeFormatString);
//this.$.matchesService.generateRequest();
},
loadMatchesList: function () {
var self = this;
$.ajax({
url: 'http://localhost:20440/MatchesService.svc/matches/GetAllForTeamInSeason',
data: {
siteId: this.siteid,
teamId: this.teamid,
seasonId: $('#fixtures-list-season-selector').val()
},
error: function () {
console.log('ajax error');
},
dataType: 'json',
success: function (data) {
console.log('fixtures-list: matches data received');
self.fixturesData = data;
},
type: 'GET'
});
},
ready: function () {
//console.log('polymer element ready');
var self = this;
if (self.isAttributeValuesReady) {
$.ajax({
url: 'http://localhost:20440/SeasonsService.svc/seasons/GetAll',
data: {
siteId: this.siteid,
teamId: this.teamid
},
error: function () {
//console.log('ajax error');
},
dataType: 'json',
success: function (data) {
//console.log('fixtures-list: season data received');
//console.log(data);
var defaultId = 0;
for (var i = 0; i < data.length; i++) {
if (i == 0) {
defaultId = data[i].Id;
}
if (i < 100) {
$('#fixtures-list-season-selector').append('<option value="' + data[i].Id + '">' + data[i].Name + '</option>');
}
if (self.seasonstarted.length > 0 && self.seasonstarted == data[i].Name) {
break;
}
}
setTimeout(function () {
console.log('init select');
$('#fixtures-list-season-selector').selectpicker('val', defaultId).on('changed.bs.select', function (e) {
self.loadMatchesList();
});
}, 500);
self.loadMatchesList();
},
type: 'GET'
});
}
},
displayDate: function (jsonDate) {
var jsDate = new Date(jsonDate.match(/\d+/)[0] * 1);
var tmpDateFormatString = this.dateformatstring;
if (tmpDateFormatString.length <= 0 || (tmpDateFormatString.length > 0 && tmpDateFormatString == 'NaN')) {
tmpDateFormatString = "ddd, d mmm";
}
return dateFormat(jsDate, tmpDateFormatString);
},
displayShortDate: function (jsonDate) {
var jsDate = new Date(jsonDate.match(/\d+/)[0] * 1);
var tmpDateFormatString = this.dateformatstring;
return dateFormat(jsDate, "d mmm");
},
displayTime: function (jsonDate) {
var jsDate = new Date(jsonDate.match(/\d+/)[0] * 1);
var tmpTimeFormatString = this.timeformatstring;
if (tmpTimeFormatString.length <= 0 || (tmpTimeFormatString.length > 0 && tmpTimeFormatString == 'NaN')) {
tmpTimeFormatString = "HH:MM";
}
return dateFormat(jsDate, tmpTimeFormatString);
},
highlightRow: function(isHome) {
var css = '';
if (isHome) {
css = 'info';
}
return css;
},
processParams: function (siteid, teamid) {
//return 'siteId='+ siteid + '&teamId=' + teamid + '&seasonId=' + $('#fixtures-list-season-selector').val();
return JSON.stringify({
siteId: siteid,
teamId: teamid,
seasonId: $('#fixtures-list-season-selector').val()
});
},
logChange: function (newValue, oldValue) {
console.log('Param changed to: ', newValue);
},
handleRequestSent: function (request) {
console.log('ReqSent');
//console.log(request);
},
handleResponseReceived: function (response) {
console.log('ResReceived');
//console.log(response);
//console.log("Received response: " + JSON.stringify(response.detail.response));
//this.result = response.detail.response;
},
handleError: function (event) {
console.log('error');
//var request = event.detail.request;
//var error = event.detail.error;
//console.log(request);
//console.log(error);
}
});
</script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.