简体   繁体   中英

Emberjs binding properties within Ember object

I am working on a web app which will display some time series data in a graph using ember-cli-chart (ChartJS wrapper). I am using socket.io to send current data to the web app to be displayed.

socket.on('timeSeriesData', function(data){
     chart1.set('outdoorTemp', data); //Sets data on signal from socket.io
});

var chart1 = Ember.Object.create({
outdoorTemp: null, //This variable is successfully set on the signal above
data: {
    labels: [], //Don't need labels for now
    datasets: [
        {
            label: "Energy Consumption in KW/H",
            fillColor: "rgba(219, 66, 0, .25)",
            strokeColor: "rgba(209, 0, 0, 1)",
            pointColor: "rgba(209, 0, 0, 1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(209, 0, 0, 1)",
            data: Ember.computed.alias('outdoorTemp') //This value does not get set to outdoorTemp
        }
    ]
},
options: {
    responsive: true,
    maintainAspectRatio: false,
    scaleFontColor: '#fff',
    scaleShowGridLines: false,
    scales: {
        yAxes: [{
            scaleLabel: {
                display: true,
                labelString: 'probability'
            }
        }]
    }
}});

My goal for this was that the graph should be updated in real time every time new data is received from socket.io. I am attempting to bind the data property to the outdoorTemp property within the chart1 object, however this data binding does not seem to work. I've read through the documentation on this matter and it looks like what I am doing should work but it does not. Would there be a more elegant solution to this problem?

This is related to your nested structure. The computed property is scoped to the local object, so in this case your alias would work for label , fillColor , etc... but can't reach its parents.

I created an ember twiddle that demonstrates this:

https://ember-twiddle.com/a91df745677ba49b5d12c9575d7dca19?openFiles=controllers.application.js%2C

I also show a solution in the twiddle which uses an observer to set the value. You could just as well try setting it directly, but maybe the intermediate function setting helps reason about how the data is sent down.

// called on init, and for any subsequent changes
setDynamic: Ember.on('init', Ember.observer('appName', function() {
      this.set('nested.observed', this.get('appName'));
}))

Observers in Ember can be dangerous, especially when they observe things that cross boundaries. This observer is local, and only sets data which in turn is not observed, so this isn't the worst use case of an observer. There might be a better solution that doesn't use an observer or setting the value on the socket.on , but at least this somewhat follows Ember's "data down, actions up" idea.

You could make the entire data root property a computed property and return the object, but that is a lot of computation for only caring about a single change and would probably be more expensive overall.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM