Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observe changes for an object in Polymer JS

Tags:

polymer

I have an element with a model object that I want to observe like so:

<polymer-element name="note-editor" attributes="noteTitle noteText noteSlug">
  <template>
    <input type="text" value="{{ model.title }}">
    <textarea value="{{ model.text }}"></textarea>
    <note-ajax-button url="/api/notes/" method="POST" model="{{model}}">Create</note-ajax-button>
  </template>

  <script>
    Polymer('note-editor', {
      attached: function() {
        this.model = {
          title: this.noteTitle,
          text: this.noteText,
          slug: this.noteSlug
        }
      },
    });
  </script>
</polymer-element>

I want to observe changes in the model but apparently it's not possible to use modelChanged callback in the element and neither in the note-ajax-button element. What is wrong? How can I do that?

I've tried observing the fields separately, but it's not clean at all. The state of the button element you see there should change depending on the model state, so I need to watch changes for the object, not the properties. Thanks!

like image 793
javivelasco Avatar asked Apr 15 '14 01:04

javivelasco


2 Answers

To observe paths in an object, you need to use an observe block:

Polymer('x-element', {
  observe: {
    'model.title': 'modelUpdated',
    'model.text': 'modelUpdated',
    'model.slug': 'modelUpdated'
  },
  ready: function() {
    this.model = {
      title: this.noteTitle,
      text: this.noteText,
      slug: this.noteSlug
    };
  },
  modelUpdated: function(oldValue, newValue) {
    var value = Path.get('model.title').getValueFrom(this);
    // newValue == value == this.model.title
  }
});

http://www.polymer-project.org/docs/polymer/polymer.html#observeblock

like image 170
ebidel Avatar answered Sep 28 '22 21:09

ebidel


Or you can add an extra attribute to your model called for example 'refresh' (boolean) and each time you modify some of the internal values also modify it simply by setting refresh = !refresh, then you can observe just one attribute instead of many. This is a good case when your model include multiple nested attributes.

Polymer('x-element', {
  observe: {
    'model.refresh': 'modelUpdated'
  },
  ready: function() {
    this.model = {
      title: this.noteTitle,
      text: this.noteText,
      slug: this.noteSlug,
      refresh: false
    };
  },
  modelUpdated: function(oldValue, newValue) {
    var value = Path.get('model.title').getValueFrom(this);
  },
  buttonClicked: function(e) {
    this.model.title = 'Title';
    this.model.text = 'Text';
    this.model.slug = 'Slug';
    this.model.refresh = !this.model.refresh;
  }
});
like image 41
Pete Kozak Avatar answered Sep 28 '22 23:09

Pete Kozak