polymerpolymer-starter-kit

Polymer 2.0 :Please Explain the how the Observer method is working in this code?


This is the code snippet but I'm not able to understand how the observer method is working

 static get properties() {
  return {
    selected: {
      type: Object,
      observer: '_selectedChanged'
    }
  };
}

_selectedChanged(selected, oldSelected) {
  if (oldSelected) oldSelected.removeAttribute('selected');
  if (selected) selected.setAttribute('selected', '');
}

connectedCallback() {
  super.connectedCallback();

  this.selected = this.firstElementChild;
}

full code: https://codelabs.developers.google.com/codelabs/polymer-2-carousel/index.html?index=..%2F..%2Findex#3

What is selected and oldselected and how can we do oldSelected.removerAttribute? Are these objects of elements? Please elaborate!


Solution

  • selected is property of element. It's value is some HTML element (in this case it's always img i think) so, in selected property there is always saved reference to img somewhere in html. When this property change, function _selectedChanged is called with 2 arguments. first argument is new image that is currently saved in selected and second argument is old image(previous value of selected).

    further in tutorial you can see code

      const elem = this.selected.nextElementSibling;
      if (elem) {
        this.selected = elem;
      }
    

    where is shown that const elem takes some html element and put it into this.selected.

    So inside function _selectedChanged they removed html attribute from old image that was previously selected (so it was visible on screen) and added new html attribute to new image that should be visible on screen for now.

    You can imagine that img with attribute selected is the only one that is shown on the screen at the time

    I hope you understand my explanation. My english isn't 100% so if you have question, ask me and i can try to explain it more.

    EDIT

    Some example with binding and observer:

    Let's say we have some paper-input which should show some results (articles for example) based on value of this input. So we have some HTML:

    <paper-input value="{{search}}" label="Find articles"></paper-input>
    

    this is primitive. Just some paper-input with value stored in search property. inside script tag:

        Polymer({
            is: 'test-el',
    
            properties: {
                search: {
                    type: String,
                    observer: "_findResults"
                },
                articles: {
                    type: Array
                }
            },
    
            _findResults() {
                this.set("articles", ['firstArticle', 'secondArticle', Math.random()]);
            },
        });
    

    Explain: we defined property search and articles. Whenever property search changes, it calls function _findResults (because of observer). Function _findResults do only one thing. this.set("articles") is almost same as this.articles =. More about this can be found in documentation. So this.set("articles", ['firstArticle', 'secondArticle', Math.random()]); means it creates array and set it to articles property. and now, when we have some array that is changing everytime user enter some value in paper-input, we can add some HTML to show these articles:

    <template is="dom-repeat" items="{{articles}}" as="item">
      [[item]] <br>
    </template>
    

    I made also fiddle, so you can play with it and understand it a little bit more. https://jsfiddle.net/2va41sy0/1/

    Your question at the beginning was almost same in difference that they stored in some property reference to HTML object and not only just string. This is also about understand some basics of javascript and not polymer