如何在只读 Polymer 1.x 属性中设置子属性

How to set sub-properties in read-only Polymer 1.x properties

如何在不完全替换其值的情况下在 Polymer 中设置只读子属性?

Polymer({
    is: 'my-element',

    properties: {
        foo: {
            type: Object,
            value: function() { return {bar:1, baz:2}; },
            readOnly: true,
            notify: true
        }
    },

    observers: [
        '_onBarChanged(foo.bar)',   // this should fire
        '_onBazChanged(foo.baz)'    // this not
    ],

    // how do I set this.foo.bar without completely replacing this.foo
    ready: function() {
        // the only way I found is completely replacing it's value
        let temp = Object.assign({}, this.foo, {bar: 3});
        this._setFoo(temp); 
    }
});

感觉好像少了什么

updating an object's subproperty 时,您应该使用 this.set('foo.baz', value) 而不是 this.foo.baz = value 以便发出更改通知。

HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',
    properties: {
      foo: {
        type: Object,
        readOnly: true,
        value: () => ({bar: 2, baz: 4})
      }
    },
    observers: [
      '_barChanged(foo.bar)',
      '_bazChanged(foo.baz)',
    ],
    _barChanged: function(bar) {
      console.log('bar', bar);
    },
    _bazChanged: function(baz) {
      console.log('baz', baz);
    },
    _changeBar: function() {
      this.set('foo.bar', this.foo.bar === 5 ? 3 : 5);
    },
    _changeBaz: function() {
      this.set('foo.baz', this.foo.baz === 3 ? 5 : 3);
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.7.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <div>bar: [[foo.bar]]</div>
      <div>baz: [[foo.baz]]</div>
      <button on-tap="_changeBar">Change bar</button>
      <button on-tap="_changeBaz">Change baz</button>
    </template>
  </dom-module>
</body>

codepen