Polymer core-localstorage - 加载预先存在的全局js变量

时间:2014-09-12 19:15:46

标签: polymer core-elements

在下面的精简代码示例中,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>

3 个答案:

答案 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>和查询实际存储空间。这意味着脚本标记将始终首先运行,这正是我们正在寻找的。

以下是一个实例:http://jsbin.com/zuvet/2/edit

请记住,在测试时,您可能必须使用dev-tools删除localstorage条目以测试默认行为。

P.S。自动绑定模板应该有一种明确的方法来设置属性默认值,可能是通过属性。

P.P.S。看看这个例子,我发现core-localstorage有一个bug。它不应该将未初始化的值存储到存储中,但它只检查null而不检查undefinedhttps://github.com/Polymer/core-localstorage/issues/5)。

答案 1 :(得分:0)

你在那里。

一个问题是,当使用JavaScript与<template is="auto-binding">内的变量进行交互时,您可以通过<template>元素上的属性进行交互。如果您要读取元素内设置的值,则需要等待template-bound事件被触发。

其次,您应该稍微设置一下默认值。我也不想对已发布的value属性使用变量名value=,尤其是如果您有多个<core-localstorage>元素(他们不能每个都发布valuevalue属性为名为<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上面的优秀解决方案一样。然而,也许杰夫可以阐明为什么一个方法/事件可能比另一个方法/事件更有效或更优先。