cicciosgamino
cicciosgamino

Reputation: 964

Polymer Element Data Binding

i'm try to create a Polymer element with a clock, simple circle and handlers with animation in CSS, so i need to update the style transform: rotate in the element template. I test the code in AngularJs and it works well, but in Polymer i cannot update the CSS property every second, the value are setted only when the element is instatiate and it seems i use the wrong way to data binding the var hourDeg, minuteDeg, secondDeg with the degrees for the clock's handlers, here the code :

// HTML code 
<link rel="import" href="../../bower_components/polymer/polymer.html">
<script src="../../bower_components/moment/moment.js"></script>

<polymer-element name="my-clock" attributes="">
  <template>
    <link rel="stylesheet" href="my-clock.css">

      <div id="hour" class="hero-hour" style="transform: rotate({{hourDeg + 'deg'}});">                       
      </div>
      <div id="minute" class="hero-minute" style="transform:rotate({{getMinuteDegree()}});"></div>
      <div id="second" class="hero-second" style="transform: rotate({{secondDeg + 'deg'}});"></div>

</template>

<script>
  ... // script reported down 
</script>
</polymer-element>

// javascript code 
(function () {

  var hour, minute, second;

  // function for update the Clock
  function updateClock(){
      var now = moment();

          second = now.seconds() * 6,
          minute = now.minutes() * 6 + second / 60,
          hour = ((now.hours() % 12) / 12) * 360 + 90 + minute / 12;
          console.log(second);
  }

  // setTimeout to update the Clock every 1000 ms
  function timedUpdate () {
      updateClock();
      setTimeout(timedUpdate, 1000);
  }

  // ok timedUpdate
  timedUpdate();

  Polymer({
    // define element prototype here
    getHourDegree: function(){
      return hour + 'deg';
    },
    getMinuteDegree: function(){
      return minute + 'deg';
    },
    getSecondDegree: function(){
      return second + 'deg';
    },
    hourDeg : this.hour,
    secondDeg : this.second
  });

 })();

so i try different solution to pass the values to div elements but i cannot update the values every 1000 ms !

Upvotes: 3

Views: 313

Answers (2)

mrts
mrts

Reputation: 18925

And here's the clock element updated to Polymer 3:

<html>
<body>
<script type="module">
  import { PolymerElement, html } from 'https://unpkg.com/@polymer/polymer/polymer-element.js?module'

  class MyClock extends PolymerElement {

    static get properties () {
      return {
        hour: Number,
        minute: Number,
        second: Number
      }
    }

    ready () {
      super.ready()
      this.updateClock()
    }

    updateClock () {
      let now = new Date()
      this.second = now.getSeconds() * 6
      this.minute = now.getMinutes() * 6 + this.second / 60
      this.hour = ((now.getHours() % 12) / 12) * 360 + 90 + this.minute / 12
      setTimeout(() => this.updateClock(), 1000)
    }

    static get template () {
      return html`
        <link rel="stylesheet" href="my-clock.css">
        <div id="hour" class="hero-hour" style="transform: rotate([[hour + 'deg']]);"></div>
        <div id="minute" class="hero-minute" style="transform: rotate([[minute + 'deg']]);"></div>
        <div id="second" class="hero-second" style="transform: rotate([[second + 'deg']]);"></div>
      `
    }
  }

  customElements.define('my-clock', MyClock)
</script>

<my-clock></my-clock>
</body>
</html>

This example works without polyfills in Chrome and Firefox, you can try this in CodePen.

Upvotes: 0

posit labs
posit labs

Reputation: 9431

You need to update attributes on the element to trigger a re-render. The element isn't watching for changes to hour, minute, second, so it doesn't re-render itself when you update those values.

Here is an example that will do what you're trying to achieve.

  <div id="hour" style="transform: rotate({{hour + 'deg'}});"></div>
  <div id="minute" style="transform: rotate({{minute + 'deg'}});"></div>
  <div id="second" style="transform: rotate({{second + 'deg'}});"></div>

....

  Polymer({
    hour : 0,
    minute : 0,
    second : 0

    domReady: function(){ 
      // start the clock when dom is ready
      setInterval(this.updateClock.bind(this), 1000);
    },

    updateClock: function(){
      var now = moment();
      // update properties to trigger re-render
      this.second = now.seconds() * 6,
      this.minute = now.minutes() * 6 + this.second / 60,
      this.hour = ((now.hours() % 12) / 12) * 360 + 90 + this.minute / 12;
    },

  });

Upvotes: 3

Related Questions