为什么将函数包装用于类型对象的Polymer属性值? [英] Why use function wrap for Polymer property value of type object?

查看:85
本文介绍了为什么将函数包装用于类型对象的Polymer属性值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将属性初始化为对象或数组值时,请使用函数来确保每个元素都具有自己的值副本,而不是在元素的所有实例之间共享对象或数组.

这是来自聚合物官方文档,我的问题是为什么不在多个实例之间共享该默认值,因为该默认值在初始化期间只会被调用一次?

    <dom-module id="title-element">
    <template>
        <h1 style$="background-color: {{backgroundColor}}">{{config.title}}</h1>
    </template>

    <script>
        Polymer({
            is: 'title-element',
            properties: {
                config: {
                    type: Object,
                    notify: true,
                    value: {
                        title: 'This is my element',
                    }
                },
                backgroundColor: String,
            },
            ready: function () {
                this.addEventListener('config-changed', function () {
                    console.log('config had changed');
                    this.querySelector('h1').style.backgroundColor = 'blue';
                })
            }
        })
    </script>
</dom-module>
<title-element background-color="yellow"></title-element>
<title-element background-color="green"></title-element>

在上面的示例中,

我尝试通过在chrome控制台中选择该元素来更改config.title的值,并使用$0.config = {"title":"any other"}notifyPath对其进行了一次更改,并且按预期,它仅在所选元素中发生了变化,并非全部实例

然后使用函数包装的目的是什么?

解决方案

使每个元素都拥有自己的副本,而不是共享它.

如果提供函数,Polymer会为每个元素实例调用一次函数.

将属性初始化为对象或数组值时,请使用 确保每个元素获取其值的副本的功能, 而不是在的所有实例之间共享一个对象或数组 元素.

这是文档

这是一个描述相同情况的简单测试用例.

 <link rel="import" href="http://polygit.org/components/polymer/polymer.html">
<dom-module id="shared-object">
  <template>
    <style></style>
    <div on-tap='changeValue'>Shared Object: {{shared.key}}</div>
    <div on-tap='changeValue'>Not Shared Object: {{notShared.key}}</div>
  </template>
</dom-module>
<script>
  Polymer({
    is: 'shared-object',
    properties: {
      shared: {
        type: Object,
        value: {
          key: 'value'
        }
      },
      notShared: {
        type: Object,
        value: function() {
          return {
            key: 'value'
          }
        }
      }
    },
    changeValue: function() {
      this.set('shared.key', 'value1');
      this.set('notShared.key', 'value1');

    }
  })
</script>
Instance one
<br>
<shared-object id='obj1'></shared-object>
<br>
<br>Instance two
<br>
<shared-object id='obj2'></shared-object>
<script>
  document.querySelector('shared-object').addEventListener('tap', function() {
    console.log('First instance:\nshared value:', document.querySelector('#obj1').shared, '\nnot shared value:', document.querySelector('#obj1').notShared);
    console.log('second instance:\nshared value:', document.querySelector('#obj2').shared, '\nnot shared value:', document.querySelector('#obj2').notShared);
  })
</script> 

点击任意值后,您会注意到,即使在所有情况下显示值都是正确的,但在控制台中shared对象的两个实例的值都相同,而notShared Object的值却不同甚至在控制台中.

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.

this is from the official polymer document my question here is why to not to share this default value across multiple instance as this default value will only be called once during initialization ??

    <dom-module id="title-element">
    <template>
        <h1 style$="background-color: {{backgroundColor}}">{{config.title}}</h1>
    </template>

    <script>
        Polymer({
            is: 'title-element',
            properties: {
                config: {
                    type: Object,
                    notify: true,
                    value: {
                        title: 'This is my element',
                    }
                },
                backgroundColor: String,
            },
            ready: function () {
                this.addEventListener('config-changed', function () {
                    console.log('config had changed');
                    this.querySelector('h1').style.backgroundColor = 'blue';
                })
            }
        })
    </script>
</dom-module>
<title-element background-color="yellow"></title-element>
<title-element background-color="green"></title-element>

in the above example i tried to change the value of config.title by selecting that element in chrome console and change it once using $0.config = {"title":"any other"} and also using notifyPath and as expected it changed only in the selected element not all instances

what is the purpose of using function wrap then ?

解决方案

So that every element gets it own copy instead of sharing it.

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.

Here's the link to documentation

Here's a simple test case to depict the same.

<link rel="import" href="http://polygit.org/components/polymer/polymer.html">
<dom-module id="shared-object">
  <template>
    <style></style>
    <div on-tap='changeValue'>Shared Object: {{shared.key}}</div>
    <div on-tap='changeValue'>Not Shared Object: {{notShared.key}}</div>
  </template>
</dom-module>
<script>
  Polymer({
    is: 'shared-object',
    properties: {
      shared: {
        type: Object,
        value: {
          key: 'value'
        }
      },
      notShared: {
        type: Object,
        value: function() {
          return {
            key: 'value'
          }
        }
      }
    },
    changeValue: function() {
      this.set('shared.key', 'value1');
      this.set('notShared.key', 'value1');

    }
  })
</script>
Instance one
<br>
<shared-object id='obj1'></shared-object>
<br>
<br>Instance two
<br>
<shared-object id='obj2'></shared-object>
<script>
  document.querySelector('shared-object').addEventListener('tap', function() {
    console.log('First instance:\nshared value:', document.querySelector('#obj1').shared, '\nnot shared value:', document.querySelector('#obj1').notShared);
    console.log('second instance:\nshared value:', document.querySelector('#obj2').shared, '\nnot shared value:', document.querySelector('#obj2').notShared);
  })
</script>

After you tap on any of the value you'll notice that even though the display values are correct for all the cases but in console shared object has same value for both the instances, whereas notSharedObject has different value even in console.

这篇关于为什么将函数包装用于类型对象的Polymer属性值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆