Polymer 1.0 observers watching a object path is not triggering even though data has changed

妖精的绣舞 提交于 2019-12-25 14:24:50

问题


jsFiddle: https://jsfiddle.net/ghstahl/09tL1ku7/

<script src="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/polymer/polymer.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-styles/paper-styles.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-styles/color.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-styles/default-theme.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-ripple/paper-ripple.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-behaviors/paper-inky-focus-behavior.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-checked-element-behavior/iron-checked-element-behavior.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-input/paper-input.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-button/paper-button.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-flex-layout/classes/iron-shadow-flex-layout.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-menu-button/paper-menu-button.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-behaviors/iron-control-state.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-behaviors/iron-button-state.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-icons/iron-icons.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-icon/iron-icon.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/iron-selector/iron-selector.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-item/paper-item.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.3/lib/paper-behaviors/paper-button-behavior.html">
<dom-module id="pingo-toggle">
<style>
    .line {
        margin-bottom: 40px;
    }
    .line span {
        margin-left: 24px;
    }
</style>
<template>
    <div class="line">
        <paper-toggle-button checked={{singleToggle.data}}></paper-toggle-button> <span>{{singleToggle.label}}</span>
<span>{{computeBooleanToString(singleToggle.data)}}</span>

    </div>
    <template is="dom-repeat" items="{{_workingArray}}">
        <div class="line">
            <paper-toggle-button checked={{item.value.data.checked}}></paper-toggle-button> 
<span>{{item.value.label}}</span>
<span>{{item.value.id}}</span>
<span>{{computeBooleanToString(item.value.data.checked)}}</span>

        </div>
    </template>
</template>
<script>
    (function() {
        Polymer({
            is: 'pingo-toggle',
            properties: {

                singleToggle: {
                    type: Object,
                    notify: true
                },

                toggleItems: {
                    type: Object,
                    notify: true,
                    observer: '_toggleItemsChanged'
                },
            },
            _toggleItemsChanged: function(newValue, oldValue) {
                if (this.toggleItems !== undefined) {
                    this._workingArray = this._toArray(this.toggleItems);
                }
            },
            _toArray: function(obj) {
                var index = 0;
                var thisElement = this;
                this._arrayData = Object.keys(obj).map(function(key) {
                    var id = "item_" + index;
                    ++index;
                    var val = {};
                    val.data = obj[key];
                    val.label = "hi:" + key;
                    val.data = obj[key];
                    val.id = id;
                    val.original = obj.key;
                    return {
                        name: key,
                        value: val
                    };
                });
                return this._arrayData;
            },
            computeBooleanToString: function(a) {
                return a === true ? 'true' : 'false';
            }
        });
    })();
</script>
</dom-module>
<dom-module id="pingo-toggle-container">
<style>
</style>
<template>
    <pingo-toggle single-toggle={{_singleToggle}} toggle-items={{_toggleItems}}></pingo-toggle>
    <paper-item>{{_singleToggleHello}}</paper-item>
    <paper-item>{{_toggleItemsHello}}</paper-item>
</template>
<script>
    (function() {
        Polymer({
            is: 'pingo-toggle-container',
            properties: {
                _singleToggleHello: {
                    type: String,
                    notify: true,
                    value: "Well Hello There"
                },
                _toggleItemsHello: {
                    type: String,
                    notify: true,
                    value: "Hi there from many"
                },

                _singleToggle: {
                    type: Object,
                    notify: true,
                    value: {
                        label: "Single Toggle",
                        data: true
                    }
                },
                _toggleItems: {
                    type: Object,
                    notify: true,
                    value: {
                        a: {
                            label: "a Toggle2",
                            checked: true
                        },
                        b: {
                            label: "a Toggle2",
                            checked: false
                        }
                    }
                }
            },

            // Observers
            /////////////////////////////////////////////////////////
            observers: ['_toggleItemsChanged(_toggleItems.*)', '_singleToggleChanged(_singleToggle.*)'],
            // Smart check. only fire if we change state.
            _singleToggleChanged: function(changeRecord) {
                var thisElement = this;

                this._singleToggleHello = this.computeBooleanToString(this._singleToggle.data) + Math.random() + changeRecord.path;
                console.log("_singleToggle in pingo-toggle-container changed:" + changeRecord.path);

            },
            _toggleItemsChanged: function(changeRecord) {
                var thisElement = this;

                this._toggleItemsHello = "_workingToggleItemsChanged fired" + Math.random() + changeRecord.path;

                console.log("pingo-toggle-container notWorking:" + changeRecord.path);

            },
            computeBooleanToString: function(a) {
                return a === true ? 'true' : 'false';
            },

            ready: function(e) {

            }
        });
    })();
</script>
</dom-module>
<pingo-toggle-container></pingo-toggle-container>

Scenario: Parent element owns a data object. Parent element passes portion of the data object to children elements which bind to values in the object. When children change the value, because they have an object reference, the data is changed directly in the parent owned master data object.

Problem: '_toggleItemsChanged(_toggleItems.*)' fires once, the very first time, but never fires again even though data in _toggleItems has changed.

Proof: In the pingo-toggle-container element;

  • Put a breakpoint at _singleToggleChanged and _toggleItemsChanged.
    • Both fire at startup.
  • Toggle both 'hi:a' and 'hi:b' back and forth.
    • nothing fires.
  • So I set 'hi:a' and 'hi:b' both to True.
  • 'Single Toggle' does fire, so I toggle that and my breakpoint hits.
    • evaluate this._toggleItems;
    • Hmm, you both are set to true. You can toggle 'hi:a' and 'hi:b' to false and redo the test. Now they are both set to false.

Why you not fire observers: ['_toggleItemsChanged(_toggleItems.)', '_singleToggleChanged(_singleToggle.)'], for data change?

Expected: I want the _toggleItemsChanged function to get called with the changeRecord.path of _toggleItems.a.checked or _toggleItems.a.checked repectively.


回答1:


I don't know if I could understand your example right, but I believe you are trying to observe a deeper sub-property change. It won't work.

Observers cannot watch that deeper. They observe the first level properties changes only when you use . If you need to go deeper, you need to observe other paths, like _toggleItems.a. and so on.



来源:https://stackoverflow.com/questions/32898959/polymer-1-0-observers-watching-a-object-path-is-not-triggering-even-though-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!