Saving screen indicators after polling using ember data

I am having problems with the ember.js + emberdata program I am creating. Below is the basic version. The problem is that every five seconds I poll for value (price) changes and I rotate the value red or green based on whether the price is up or down. Please note that in the real problem I am showing css animation, not just css color change. Every time I reload the model, this resets this value. How can I make it so that, for example, the red / green color persists for seven seconds, not just five? So if there is a price change, I would show green for seven seconds and ignore any changes that were made during the color change. Feel free to ask for more details, I may have forgotten.Any constructive implementation comments are also welcome. Below are examples of programs and settings:

Web application side

test_ember_code.js

(function() {
  var App;

  App = Ember.Application.create({
    LOG_TRANSITIONS: true,
    LOG_BINDINGS: true,
    LOG_VIEW_LOOKUPS: true,
    LOG_STACKTRACE_ON_DEPRECATION: true,
    LOG_VERSION: true,
    debugMode: true
  });

  App.Router.map(function() {
    return this.resource("product");
  });

  App.IndexRoute = Ember.Route.extend({
    redirect: function() {
      this.transitionTo("product");
    }
  });

  App.Product = DS.Model.extend({
    price: DS.attr('number', {
      "default": 1
    }),
    oldPrice: DS.attr('number', {
      "default": null
    }),
    storeOldPrice: function() {
      return this.set('oldPrice', this.get('price'));
    },
    priceChanged: (function() {
      if (this.get('oldPrice') != null) {
        return this.get('price') !== this.get('oldPrice');
      } else {
        return false;
      }
    }).property('price', 'oldPrice'),
    priceMovedUp: (function() {
      if (this.get('oldPrice') != null) {
        return this.get('price') > this.get('oldPrice');
      } else {
        return false;
      }
    }).property('price', 'oldPrice'),
    priceFormatted: (function() {
      if (this.get('price')) {
        return this.get('price').toFixed(2);
      }
    }).property('price', 'oldPrice'),
    oldPriceFormatted: (function() {
      if (this.get('oldPrice')) {
        return this.get('oldPrice').toFixed(2);
      } else {
        return 0.00;
      }
    }).property('oldPrice')
  });

  App.ProductAdapter = DS.RESTAdapter.extend({
    findAll: function(store, type, sinceToken) {
      return this.ajax('http://localhost:3000', 'GET');
    }
  });

  App.ProductController = Em.ArrayController.extend({
    backupPrices: function() {
      return this.get('model').filter(function(product) {
        return product.storeOldPrice();
      });
    }
  });

  App.ProductSerializer = DS.RESTSerializer.extend({
    extractArray: function(store, type, payload) {
      return this._super(store, type, payload);
    }
  });

  App.ProductRoute = Ember.Route.extend({
    model: function() {
      console.log('model load');
      return this.store.findAll('product');
    },
    setupController: function(controller, model) {
      console.log('setting up controller');
      this._super(controller, model);
      return Em.run.later(this, this.startPolling, 5000);
    },
    startPolling: function() {
      this.set('polling', true);
      return Em.run.later(this, this.refresh, 5000);
    },
    refresh: function() {
      if (!this.get('polling')) {
        return;
      }
      console.log('polling');
      this.controller.backupPrices();
      this.store.findAll('product');
      return Em.run.later(this, this.refresh, 5000);
    },
    actions: {
      willTransition: function() {
        return this.set('refreshing', false);
      }
    }
  });

}).call(this);

      

index.html

<html>
    <head>
        <style>
            .up{
                background-color:green;
            }
            .down{
                background-color:red;
            }
        </style>
    </head>
    <body>
        <script type="text/x-handlebars" id="application">
            <h1>Price Update Test</h1>
            {{outlet}}
        </script>
        <script type="text/x-handlebars" id="index"></script>
        <script type="text/x-handlebars" id="product">
            {{#each}}
                <p>
                    Current Price:  
                    <span {{bind-attr class="priceChanged priceMovedUp:up:down"}}>
                        {{priceFormatted}}
                    </span>
                </p>

                <p>
                    Old Price:
                    <span> 
                        {{oldPriceFormatted}}
                    </span>
                </p>
            {{/each}}
        </script>
        <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
        <script src="http://builds.emberjs.com/canary/ember.prod.js"></script>
        <script src="http://builds.emberjs.com/canary/ember-data.js"></script>  
        <script src="test_ember_code.js"></script>
    </body>
</html>

      

Node server side

package.json

{
  "name": "priceChangeServer",
  "version": "0.0.0",
  "description": "Simple http service that returns a data to show a random number to simulate price changes",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.10.1"
  }
}

      

server.js

var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  randomValue1 = Math.floor(Math.random() * 100) + 1;
  randomValue2 = Math.floor(Math.random() * 100) + 1;
  res.send('{"products":[{"id":1,"price":'+randomValue1+'},{"id":2,"price":'+randomValue2+'}]}');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

      

How to run webapp

Create the following folder structure

layout for this app

Enter the server_app folder and run "npm install". Then start 'node server.js' (assuming you have node installed and configured correctly, if not, you need to start it). He should say "listen": 3000.

Then go to the web_app folder and open index.html in your browser. Note. You may need to launch your browser with web security disabled. Chrome will complain about CORS issues since the server is running on localhost and the web app is not. For chrome, starting with the --disable-web-security flag. for example: 'c: \ Program Files (x86) \ Google \ Chrome \ Application \ chrome.exe --disable-web-security' on windows.

You will now see the current price changing every five seconds, as well as the color change depending on whether it is red or green. This is a demo.

+3


source to share


1 answer


Move the code where you are pulling new data from the model (route) to the controller. Then the value will never go back to 0 and you won't get weird flickering problem.



Hope that helps :)

0


source







All Articles