单向发送数据时聚合物结合
Polymer Binds when Data sent One Way
我目前正在一个项目中使用 Polymer,出于某种原因,我在既不期望也不想要的时候获取数据绑定。
我目前拥有的是一个样板 Polymer 项目,该项目应该包含我创建的新元素(名为 shokka-eval-chart)。这很好用,但不知何故信息正在三个元素之间共享。
为了调试这个问题,我添加了 console.log 消息,告诉我发生了什么。每次控制台日志返回时,都表明 userData 已被修改。这种修改发生在哪里?为什么?
您可能会注意到的一些事情:
- 使用一种数据绑定方式发送用户数据::: [[userInfo.evaluations]]
- 不应该通知索引我对用户数据的更改::: 通知: false
一些我能想到的可能有问题的地方:
- HTML - 我可能没有正确地将东西传递到标签中。
- Javascript - 我不知道如何修改用户数据。
- 聚合物 - 显而易见的位置。我可能误解了其中一个概念。
请让我知道这是哪里发生的,以及我做错了什么导致发生这种情况。提前致谢。
控制台日志
shokka-eval-chart.html:89 Jan 16
shokka-eval-chart.html:91 40
shokka-eval-chart.html:92 40
shokka-eval-chart.html:93 0
shokka-eval-chart.html:89 Jan 16
shokka-eval-chart.html:91 0
shokka-eval-chart.html:92 40
shokka-eval-chart.html:93 -40
shokka-eval-chart.html:89 Jan 16
shokka-eval-chart.html:91 -40
shokka-eval-chart.html:92 40
shokka-eval-chart.html:93 -80
索引
<body unresolved class="fullbleed layout vertical">
<span id="browser-sync-binding"></span>
<template is="dom-bind" id="app">
<paper-drawer-panel id="paperDrawerPanel">
<paper-scroll-header-panel main condenses keep-condensed-header>
<div class="content">
<iron-pages attr-for-selected="data-route" selected="{{route}}">
<section data-route="home">
<paper-material elevation="1">
<shokka-eval-chart id="comparison1"
user-evaluations="[[userInfo.evaluations]]"
eval-ref="{{baseRef}}/evalResults">
</shokka-eval-chart>
</paper-material>
<paper-material elevation="1">
<shokka-eval-chart id="comparison2"
user-evaluations="[[userInfo.evaluations]]"
eval-ref="{{baseRef}}/evalResults">
</shokka-eval-chart>
</paper-material>
<paper-material elevation="1">
<shokka-eval-chart id="comparison3"
user-evaluations="[[userInfo.evaluations]]"
eval-ref="{{baseRef}}/evalResults">
</shokka-eval-chart>
</paper-material>
</section>
</iron-pages>
</div>
</paper-scroll-header-panel>
...
组件代码
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="shokka-eval-chart">
<template>
<style>
:host {
display: block;
}
</style>
<google-chart id="{{id}}"
type="{{type}}"
options='{{options}}'
data='[[data]]'>
</google-chart>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'shokka-eval-chart',
properties: {
id: {
type: String
},
userEvaluations: {
type: String
},
evalRef: {
type: String
},
userData: {
type: Array,
value: [ ["Date", "Professionalism", "Skills", "Work Completion" ],
["Jan 16", 40, 35, 37 ],
["Feb 16", 39, 35, 34 ],
["Mar 16", 38, 36, 39 ],
["Apr 16", 42, 38, 40 ],
["May 16", 42, 37, 41 ],
["Jun 16", 43, 38, 40 ],
["Jul 16", 44, 40, 41 ],
["Aug 16", 45, 43, 42 ],
["Sep 16", 46, 46, 41 ],
["Oct 16", 45, 44, 42 ] ],
notify: false
},
data: {
type: Array,
computed: 'computeData(avgData, userData)',
notify: false
},
options: {
type: Object,
value: { "title": "Evaluation Comparison" }
},
type: {
type: String,
value: "column"
},
avgData: {
type: Array,
value: [ ["Date", "Professionalism", "Skills", "Work Completion" ],
["Jan 16", 40, 40, 40 ],
["Feb 16", 40, 40, 40 ],
["Mar 16", 40, 40, 40 ],
["Apr 16", 40, 40, 40 ],
["May 16", 40, 40, 40 ],
["Jun 16", 40, 40, 40 ],
["Jul 16", 40, 40, 40 ],
["Aug 16", 40, 40, 40 ],
["Sep 16", 40, 40, 40 ],
["Oct 16", 40, 40, 40 ] ],
notify: false
}
},
computeData: function(avgData, userData){
console.log(userData[1][0])
var data = userData.slice();
console.log(userData[1][1])
console.log(avgData[1][1])
console.log(userData[1][1]-avgData[1][1])
data[1][1] = userData[1][1] - avgData[1][1]
return data;
}
});
})();
</script>
</dom-module>
更新:
根据 Günter Zöchbauer 的建议,我已将 var data = userData;
更改为 var data = userData.slice();
。然而,这还没有解决问题。我似乎还缺少其他东西。
更新:
在修改数据后查看 userData 后,它似乎仍指向同一个对象。我将 var data = userData.slice();
更改为
var data = [];
for (var i = 0, len = userData.length; i < len; i++) {
data[i] = userData[i].slice();
}
为了解决这个问题。这已经解决了我遇到的问题,但仍然让我想知道为什么 userData 是从不同的标签修改的。如果有人可以评论并告诉我为什么会非常感激。
我怀疑你期待这条线
var data = userData;
创建 userData
的副本,但在此行之后,data
和 userData
指向相同的数据结构。
试试看
var data = userData.splice();
只是猜测。如果这不是问题,我不知道是什么导致了问题。
这可能是它,但我不记得我自己尝试时它是否有效。我在下面用斜体强调。
Configuring default property values
Default values for properties may be specified in the properties object using the value field. The value may either be a primitive value, or a function that returns a value.
If you provide a function, Polymer calls the function once per element instance.
When initializing a property to an object or array value, use a function to ensure that each element gets its own copy of the value, rather than having an object or array shared across all instances of the element.
data: {
type: Object,
value: function() { return {}; }
}
来源:https://www.polymer-project.org/1.0/docs/devguide/properties#configure-values
我目前正在一个项目中使用 Polymer,出于某种原因,我在既不期望也不想要的时候获取数据绑定。
我目前拥有的是一个样板 Polymer 项目,该项目应该包含我创建的新元素(名为 shokka-eval-chart)。这很好用,但不知何故信息正在三个元素之间共享。
为了调试这个问题,我添加了 console.log 消息,告诉我发生了什么。每次控制台日志返回时,都表明 userData 已被修改。这种修改发生在哪里?为什么?
您可能会注意到的一些事情:
- 使用一种数据绑定方式发送用户数据::: [[userInfo.evaluations]]
- 不应该通知索引我对用户数据的更改::: 通知: false
一些我能想到的可能有问题的地方:
- HTML - 我可能没有正确地将东西传递到标签中。
- Javascript - 我不知道如何修改用户数据。
- 聚合物 - 显而易见的位置。我可能误解了其中一个概念。
请让我知道这是哪里发生的,以及我做错了什么导致发生这种情况。提前致谢。
控制台日志
shokka-eval-chart.html:89 Jan 16
shokka-eval-chart.html:91 40
shokka-eval-chart.html:92 40
shokka-eval-chart.html:93 0
shokka-eval-chart.html:89 Jan 16
shokka-eval-chart.html:91 0
shokka-eval-chart.html:92 40
shokka-eval-chart.html:93 -40
shokka-eval-chart.html:89 Jan 16
shokka-eval-chart.html:91 -40
shokka-eval-chart.html:92 40
shokka-eval-chart.html:93 -80
索引
<body unresolved class="fullbleed layout vertical">
<span id="browser-sync-binding"></span>
<template is="dom-bind" id="app">
<paper-drawer-panel id="paperDrawerPanel">
<paper-scroll-header-panel main condenses keep-condensed-header>
<div class="content">
<iron-pages attr-for-selected="data-route" selected="{{route}}">
<section data-route="home">
<paper-material elevation="1">
<shokka-eval-chart id="comparison1"
user-evaluations="[[userInfo.evaluations]]"
eval-ref="{{baseRef}}/evalResults">
</shokka-eval-chart>
</paper-material>
<paper-material elevation="1">
<shokka-eval-chart id="comparison2"
user-evaluations="[[userInfo.evaluations]]"
eval-ref="{{baseRef}}/evalResults">
</shokka-eval-chart>
</paper-material>
<paper-material elevation="1">
<shokka-eval-chart id="comparison3"
user-evaluations="[[userInfo.evaluations]]"
eval-ref="{{baseRef}}/evalResults">
</shokka-eval-chart>
</paper-material>
</section>
</iron-pages>
</div>
</paper-scroll-header-panel>
...
组件代码
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="shokka-eval-chart">
<template>
<style>
:host {
display: block;
}
</style>
<google-chart id="{{id}}"
type="{{type}}"
options='{{options}}'
data='[[data]]'>
</google-chart>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'shokka-eval-chart',
properties: {
id: {
type: String
},
userEvaluations: {
type: String
},
evalRef: {
type: String
},
userData: {
type: Array,
value: [ ["Date", "Professionalism", "Skills", "Work Completion" ],
["Jan 16", 40, 35, 37 ],
["Feb 16", 39, 35, 34 ],
["Mar 16", 38, 36, 39 ],
["Apr 16", 42, 38, 40 ],
["May 16", 42, 37, 41 ],
["Jun 16", 43, 38, 40 ],
["Jul 16", 44, 40, 41 ],
["Aug 16", 45, 43, 42 ],
["Sep 16", 46, 46, 41 ],
["Oct 16", 45, 44, 42 ] ],
notify: false
},
data: {
type: Array,
computed: 'computeData(avgData, userData)',
notify: false
},
options: {
type: Object,
value: { "title": "Evaluation Comparison" }
},
type: {
type: String,
value: "column"
},
avgData: {
type: Array,
value: [ ["Date", "Professionalism", "Skills", "Work Completion" ],
["Jan 16", 40, 40, 40 ],
["Feb 16", 40, 40, 40 ],
["Mar 16", 40, 40, 40 ],
["Apr 16", 40, 40, 40 ],
["May 16", 40, 40, 40 ],
["Jun 16", 40, 40, 40 ],
["Jul 16", 40, 40, 40 ],
["Aug 16", 40, 40, 40 ],
["Sep 16", 40, 40, 40 ],
["Oct 16", 40, 40, 40 ] ],
notify: false
}
},
computeData: function(avgData, userData){
console.log(userData[1][0])
var data = userData.slice();
console.log(userData[1][1])
console.log(avgData[1][1])
console.log(userData[1][1]-avgData[1][1])
data[1][1] = userData[1][1] - avgData[1][1]
return data;
}
});
})();
</script>
</dom-module>
更新:
根据 Günter Zöchbauer 的建议,我已将 var data = userData;
更改为 var data = userData.slice();
。然而,这还没有解决问题。我似乎还缺少其他东西。
更新:
在修改数据后查看 userData 后,它似乎仍指向同一个对象。我将 var data = userData.slice();
更改为
var data = [];
for (var i = 0, len = userData.length; i < len; i++) {
data[i] = userData[i].slice();
}
为了解决这个问题。这已经解决了我遇到的问题,但仍然让我想知道为什么 userData 是从不同的标签修改的。如果有人可以评论并告诉我为什么会非常感激。
我怀疑你期待这条线
var data = userData;
创建 userData
的副本,但在此行之后,data
和 userData
指向相同的数据结构。
试试看
var data = userData.splice();
只是猜测。如果这不是问题,我不知道是什么导致了问题。
这可能是它,但我不记得我自己尝试时它是否有效。我在下面用斜体强调。
Configuring default property values
Default values for properties may be specified in the properties object using the value field. The value may either be a primitive value, or a function that returns a value.
If you provide a function, Polymer calls the function once per element instance.
When initializing a property to an object or array value, use a function to ensure that each element gets its own copy of the value, rather than having an object or array shared across all instances of the element.
data: {
type: Object,
value: function() { return {}; }
}
来源:https://www.polymer-project.org/1.0/docs/devguide/properties#configure-values