javascript 聚合物全局变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24867741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Polymer global variables
提问by Greg Johnson
I'm working on a Polymer app, which is pulling data from a RESTful API and using it to construct the interface. A specific area I'm stuck on conceptually is the implementation of the Monostate Pattern described at http://www.polymer-project.org/docs/polymer/polymer.html#global. Effectively, I can add declarative attributes into a new component, app-globals, and then access this reasonably straightforwardly.
我正在开发一个 Polymer 应用程序,它从 RESTful API 中提取数据并使用它来构建接口。我在概念上坚持的一个特定领域是http://www.polymer-project.org/docs/polymer/polymer.html#global 中描述的 Monostate 模式的实现。实际上,我可以将声明性属性添加到新组件 app-globals 中,然后相当直接地访问它。
Here's the key question: if I'm pulling (and, potentially, resubmitting) data back and forth via core-ajax to the API within the app-globals component, how do I ensure that all consumers of the app-globals component have the same data? Seems like I've lost my monostatism if I use the suggested pattern:
这是关键问题:如果我通过 core-ajax 向 app-globals 组件内的 API 来回拉取(并可能重新提交)数据,我如何确保 app-globals 组件的所有使用者都拥有相同的数据?如果我使用建议的模式,似乎我已经失去了我的单一性:
<polymer-element name="my-component">
<template>
<app-globals id="globals"></app-globals>
<div id="firstname"></div>
<div id="lastname"></div>
</template>
<script>
Polymer('my-component', {
ready: function() { this.globals = this.$.globals; }
});
</script>
</polymer-element>
because each of the components that consume app-globals will be pulling their own version of the API data. Am I missing something? Is there another way to ensure that the app constantly has only one version of the truth?
因为每个使用 app-globals 的组件都将提取自己版本的 API 数据。我错过了什么吗?有没有另一种方法可以确保应用程序始终只有一个版本的真相?
采纳答案by Tim Stewart
Each time you reference app-globals in a custom component, a new instance of app-globals is created. But each of these instances can share a number of properties (think "static" vars in Java or "class" vars in ObjC / Swift).
每次在自定义组件中引用 app-globals 时,都会创建一个新的 app-globals 实例。但是这些实例中的每一个都可以共享许多属性(想想 Java 中的“静态”变量或 ObjC/Swift 中的“类”变量)。
The Script within app-globals element (or indeed any Polymer element) runs only once - think of it as running when the component definition is loaded. But the Polymer function within that script declares a configuration object, with properties and lifecycle event-handlers, that will be created separately for each instance. The app-globals script in the document you reference (copied below UPDATE: this version is modified as described later) uses an anonymous closure (a function that is run immediately), containing both the shared variables and the Polymer function declaring the config object which in turn references the shared variables. So each instance of that config object - and in turn each instance of app-globals - will reference the same set of shared variables.
app-globals 元素(或任何 Polymer 元素)中的脚本仅运行一次 - 将其视为在加载组件定义时运行。但是该脚本中的 Polymer 函数声明了一个配置对象,具有属性和生命周期事件处理程序,将为每个实例单独创建。您引用的文档中的 app-globals 脚本(复制到 UPDATE 下方:此版本的修改如下所述)使用匿名闭包(立即运行的函数),其中包含共享变量和声明配置对象的 Polymer 函数依次引用共享变量。因此,该配置对象的每个实例 - 进而每个 app-globals 实例 - 将引用相同的共享变量集。
<polymer-element name="app-globals">
<script>
(function() {
var data = {
firstName: 'John',
lastName: 'Smith'
}
Polymer('app-globals', {
ready: function() {
this.data = data;
}
});
})();
</script>
</polymer-element>
If one custom component instance changes a value on its app-globals instance (or they are changed internally, as the results of an AJAX call in your case) allother component instances with a reference to app-globals will see the changed value.
如果一个自定义组件实例更改了其 app-globals 实例上的值(或者它们在内部发生了更改,作为 AJAX 调用的结果),所有其他引用 app-globals 的组件实例都将看到更改后的值。
UPDATE: The original, as copied from:
更新:原件,复制自:
http://www.polymer-project.org/docs/polymer/polymer.html#global
http://www.polymer-project.org/docs/polymer/polymer.html#global
had a deficiency, as described by @zreptil, if you change the data values, the new values are NOT available to all other instances - because the instance variables are just copies of the referenced strings. By using an object with data properties, as in the edited version above, and only ever reading from and assigning to the data properties of that object rather than overwriting the object itself, changed values are shareable between instances.
有一个缺陷,如@zreptil 所述,如果您更改数据值,则新值不适用于所有其他实例 - 因为实例变量只是引用字符串的副本。通过使用具有数据属性的对象,如在上面的编辑版本中,并且只读取和分配该对象的数据属性而不是覆盖对象本身,更改的值可以在实例之间共享。
回答by ootwch
@Zreptil has asked for an example above, and since I had to experiment with this anyway I built one based on Tim Stewart's answer and the Polymer documentation.
@Zreptil 要求提供上面的示例,并且由于无论如何我都必须对此进行试验,因此我根据 Tim Stewart 的回答和 Polymer 文档构建了一个示例。
Complete Example: http://jsbin.com/figizaxihe/1/edit?html,output
完整示例:http: //jsbin.com/figizaxihe/1/edit?html,output
I had some troubles with dashes in the id (id="global-variable"
) so I also added an example for that.
我在 id ( id="global-variable"
) 中使用破折号时遇到了一些麻烦,因此我还为此添加了一个示例。
The element definition
元素定义
<polymer-element name="app-globals">
<script>
(function() {
var data = {
firstName: 'John'
}
Polymer({
ready: function() {
this.data = data;
}
});
})();
</script>
</polymer-element>
Use it inside a polymer element
在聚合物元件内使用它
<polymer-element name="output-element" noscript>
<template>
<app-globals id="globalvars"></app-globals>
<h4>Output-Element</h4>
<div>First Name: {{$.globalvars.data.firstName}}</div>
</template>
</polymer-element>
Use it outside a polymer element
在聚合物元件外使用
<template is="auto-binding">
<app-globals id="topglobals"></app-globals>
<h3>First Name in Title: {{$.topglobals.data.firstName}}</h3>
</template>
Pay attention with dashes/hyphens
注意破折号/连字符
<h3>and since that took me a while to realize - dashes are not directly supported...</h3>
<template is="auto-binding">
<!-- can use different id's -->
<app-globals id="global-variables"></app-globals>
<div>This does not work: {{$.global-variables.data.firstName}}</div>
<div>Correct syntax: {{$['global-variables'].data.firstName}}</div>
</template>
Polymer 1.0
聚合物 1.0
See Polymer 1.0 Global Variablesfor a polymer 1.0 solution if interested.
如果有兴趣,请参阅Polymer 1.0 Global Variables了解聚合物 1.0 解决方案。