-->

Why use function wrap for Polymer property value o

2019-09-05 01:22发布

问题:

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 ?

回答1:

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.