在下面的精简代码示例中,core-localstorage元素不应该将全局js变量`itemsApiURL'的值加载到{{value}}中,以便在将其传递给my-datasource-element时那个自定义元素准备好了?或者core-localstorage的目的是限于将值写入localstorage?目前,在my-datasource-element的ready()事件中,{{value}}未定义,尽管它作为全局变量存在(理想情况下设置在外部js配置文件中,不包括在头部中,如此处所示)。我绝对不会做正确的事情......也许我对js缺乏安慰,或某种范围/事件顺序问题。
也许有一个更好的方法来配置聚合物应用程序范围的变量/常量,以便可以轻松地使用我的所有应用程序元素的值,或者至少通过双向数据绑定作为元素属性传递?这真的是我认为更重要的问题......但无论哪种方式,我仍然对核心本地存储的运作方式感到困惑。
<html>
<head>
<script>
this.itemsApiURL = "http://server:port/api/items";
</script>
<link rel="import" href="./components/platform/platform.js">
<link rel="import" href="./components/core-localstorage/core-localstorage.html">
</head>
<body fullbleed unresolved>
<template is="auto-binding">
<core-localstorage name="itemsApiURL" value="{{value}}"></core-localstorage>
<my-datasource-element url="{{value}}" items="{{items}}"><my-datasource-element>
</template>
</body>
</html>
答案 0 :(得分:1)
尽可能地,Polymer希望您不必担心时序问题(也就是将事件视为时序信号)。特别是,因为元素升级保留了属性值,事件和其他元素功能,所以当您需要将值戳到元素中时,通常可以立即执行此操作。
,例如,在这种情况下,您可以简化为:
<template is="auto-binding">
<core-localstorage name="itemsApiURL"
value="{{itemsApiURL}}"></core-localstorage>
<label for="inputElement">itemsApiURL:</label>
<input type="text"
id="inputElement"
value="{{itemsApiURL}}"
size="50">
</template>
<script>
document.querySelector('template').itemsApiURL =
'http://server:port/api/items';
</script>
看起来我们正在考虑<script>
标记和<core-localstorage>
关于itemsApiURL
的值,但Polymer在创建之间创建了异步 <core-localstorage>
和查询实际存储空间。这意味着脚本标记将始终首先运行,这正是我们正在寻找的。 p>
以下是一个实例:http://jsbin.com/zuvet/2/edit
请记住,在测试时,您可能必须使用dev-tools删除localstorage条目以测试默认行为。
P.S。自动绑定模板应该有一种明确的方法来设置属性默认值,可能是通过属性。
P.P.S。看看这个例子,我发现core-localstorage
有一个bug。它不应该将未初始化的值存储到存储中,但它只检查null
而不检查undefined
(https://github.com/Polymer/core-localstorage/issues/5)。
答案 1 :(得分:0)
你在那里。
一个问题是,当使用JavaScript与<template is="auto-binding">
内的变量进行交互时,您可以通过<template>
元素上的属性进行交互。如果您要读取元素内设置的值,则需要等待template-bound
事件被触发。
其次,您应该稍微设置一下默认值。我也不想对已发布的value
属性使用变量名value=
,尤其是如果您有多个<core-localstorage>
元素(他们不能每个都发布value
个value
属性为名为<input type="text">
)的变量。
这是一个可以捕捉您正在尝试做的事情的工作示例。 (Live version on JSBin。)每当您更改"http://server:port/api/items"
中的值时,更新后的值都会写入本地存储空间,并且您第一次访问该页面时,会使用默认值<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Polymer Demo</title>
</head>
<body>
<script src="http://www.polymer-project.org/platform.js"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
<link rel="import" href="http://www.polymer-project.org/components/core-localstorage/core-localstorage.html">
<template is="auto-binding">
<core-localstorage name="itemsApiURL"
value="{{itemsApiURL}}">
</core-localstorage>
<label for="inputElement">itemsApiURL:</label>
<input type="text"
id="inputElement"
value="{{itemsApiURL}}"
size="50">
</template>
<script>
var template = document.querySelector('template');
template.addEventListener('template-bound', function() {
template.itemsApiURL = template.itemsApiURL || 'http://server:port/api/items';
// You can do something with template.itemsApiURL
// like use it to make an API call, etc.
});
</script>
</body>
</html>
{{1}}
答案 2 :(得分:0)
在我看到杰夫的出色和彻底的反应之前,我做了下面的工作(与Jeff的解决方案一样,但是针对不同的事件):
首先,我调整了一些现有的元素属性/命名,如下所示:
<core-localstorage id="datasourceURL" name="itemsURL" value="{{itemsURL}}"></core-localstorage>
<my-datasource-element url="{{itemsURL}}" items="{{items}}"></my-datasource-element>
然后我将onload="loadItemsURL()"
添加到body
代码。
接下来,当然需要编写loadItemsURL函数脚本并定义事件侦听器。在这种情况下,我决定监听core-localstorage-load
(核心元素本身实现此事件):
function loadItemsURL() {
window.addEventListener('core-localstorage-load', function(event) {
// Load base api URL for items collection from pre-existing global js variable (happens to be stored in external items.js)
// This forces core-localstorage element to refresh its value (and populate polymer {{itemsURL}} )
// in turn triggering datasource element to run ajax call
// (as it happens to be set to 'auto' get when it's URL attribute or params change)
this.datasourceURL.value = this.itemsURL;
});
}
这对我来说很有把握,就像Jeff上面的优秀解决方案一样。然而,也许杰夫可以阐明为什么一个方法/事件可能比另一个方法/事件更有效或更优先。