7

I have an amount of properties I want to observe with the same shared observer. Let’s say, I want to track modification history. Unfortunately, the standard polymer observer callback, according to the documentation, has an artless prototype:

myObserver: function(oldValue, newValue) {}

Since I want to keep track on changes, I need to know the name of the property changed. By reverse engineering the arguments of myObserver, I surprisingly discovered, that there is a third argument of type Arguments[3] passed to the function. So the code^W woodoo-magic below would do the trick:

myObserver: function() {
  if (arguments.length > 2) { // observer called by polymer
    var args = arguments[2];
    var idx = args[1].length - 1; // sic! index of changed is stored in index 
    var prop = args[2][idx * 2 + 1][0];
    var val = args[0][idx];

    console.log("Property [" + prop + "] got new value: " + val);
  }
  ...
}

Being sane and craving to stay sane, I want to know whether I missed more amiable way to get the changed attribute name from the observer.

@ebidel and @robdodson would you please shed some light on that? Would the arguments[2] be supported in newest versions? Is there a better way to react on changes?

Thanks in advance.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160

2 Answers2

0

I think you are looking for a different mechanism. If indeed you would accept to adopt a different mechanism to implement the functionality you need it might not hurt to check out MutationObserver. I have managed to play around with the demo in this answer and could easily log my chrome console the elements this MutationObserver was observing.

Hope this helps !

Community
  • 1
  • 1
vortex
  • 862
  • 8
  • 14
  • Yes, thanks, I know about `MutationObserver`. I could even use `DOMSubtreeModified` event listener. The question was about using of already existing event handler, provided by _Polymer_. – Aleksei Matiushkin Feb 23 '15 at 06:37
0

So, if I understand correctly, the goal is to use a single observer for multiple property changes, and inside of the observer you need to be able to determine the name of the property that changed.

I experimented around a little bit and found out that you can achieve this with a deep sub-property observers.

<!doctype html>
<html>
<head>
<meta name="description" content="http://stackoverflow.com/questions/28265025">
  <meta charset="utf-8">
  <base href="http://polygit.org/components/">
  <script href="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">
</head>
<body>
  <dom-module id="x-el">
    <template>
      <p>path: {{path}}</p>
      <p>value: {{value}}</p>
      <button on-click="incrementNumber1">increment number 1</button>
      <button on-click="incrementNumber2">increment number 2</button>      
    </template>
    <script>
      Polymer({
        is: 'x-el',
        properties: {
          path: {
            type: String,
            notify: true
          },
          value: {
            type: String,
            notify: true
          },
          number1: {
            type: Number,
            value: 0,
            notify: true
          },
          number2: {
            type: Number,
            value: 0,
            notify: true
          },
        },
        observers: [
          'onChange(number1.*)',
          'onChange(number2.*)'
        ],
        incrementNumber1: function() {
          this.number1 += 1;
        },
        incrementNumber2: function() {
          this.number2 += 1;
        },        
        onChange: function(changeRecord) {
          this.path = changeRecord.path;
          this.value = changeRecord.value;
        }
      });
    </script>
  </dom-module>
  <x-el></x-el>
</body>
</html>

https://jsbin.com/pufexay/edit?html,output

Kayce Basques
  • 23,849
  • 11
  • 86
  • 120