Community Tip - Visit the PTCooler (the community lounge) to get to know your fellow community members and check out some of Dale's Friday Humor posts! X
Hello ThingWorx wizards,
In my mashup I execute a service every ten seconds, and then use the returned InfoTable to render a Repeater. The data changes are rare, so in 90% of the cases the returned InfoTable is the same.
My problem is that the repeater gets visibly re-rendered every time the service returns, even if the data didn't actually change. Is there any reasonably elegant way to avoid refreshing the Repeater in this case?
/ Constantine
Solved! Go to Solution.
I would say the best way to do this, right now, would be the following (pasted from an older blog of mine):
Edit |
Most of the time when we want to see new data in a Mashup we use the familiar AutoRefresh widget, set with a interval not too high or low, so it makes the page feel responsive but also not generating lots of traffic.
Also, there are some problems if you trigger services which take some time in order to execute.
This can be mitigated in a simple way, if the architecture allows it, with a simple workaround, involving the use of a DirtyFlag:
Presumption: you have a mashup with a service called Query.... which supplies information for a grid or map.
1. Create a property called DirtyFlag, located anywhere you want
2. Add a GetProperty service which gets the value of the DirtyFlag in the mashup.
3. In your mashup, add a Validator, configure an Input Parameter called "DirtyFlag", and type boolean. In the expression write "DirtyFlag == true". Check the AutoEvaluate checkbox.
4. Set/bind the Validator input parameter value to the value of the DirtyFlag property from the GetProperty service.
5. Bind the Autorefresh event to the GetProperties service.
Explanation: untill now, we make sure that the True event of the validator fires each time when the DirtyFlag property is set to true.
6. Bind the True event of the Validator to the Query type services
7. Create a new service (located anywhere you want) that sets the DirtyFlag property to true. Let's call this service "ResetDirtyFlag"
8. Add the new Service in the mashup
9. Bind the ServiceInvokeCompleted event of the Query service to the ResetDirtyFlag service
10.Done? Not quite yet!
11. Now you must make sure you also set the DirtyFlag property (we still didn't do that yet). Ideally you should do this where you add/update rows to that datatable/stream/infotable etc.
12. Now it's done
So, we have now lots of requests only for small amounts of data (the GetProperties), and only when we see lots of data.
Constantine, I don't believe there is a way to actually stop the repeater from refreshing, as it is simply rendering your Mashup. What is your ItemLoadBehavior set to? You can stop the repeater from re-renedering your rows if you set it to Load/ No Unload.
A quick band-aid would be to uncheck 'ShowDataLoading'. That would stop the repeater from displaying the loading bar, hence giving the effect of 'not refreshing every couple seconds'
Why don't you create a service which checks if there's updates or not, if there isn't any update don't call the real pick data service.
I would say the best way to do this, right now, would be the following (pasted from an older blog of mine):
Edit |
Most of the time when we want to see new data in a Mashup we use the familiar AutoRefresh widget, set with a interval not too high or low, so it makes the page feel responsive but also not generating lots of traffic.
Also, there are some problems if you trigger services which take some time in order to execute.
This can be mitigated in a simple way, if the architecture allows it, with a simple workaround, involving the use of a DirtyFlag:
Presumption: you have a mashup with a service called Query.... which supplies information for a grid or map.
1. Create a property called DirtyFlag, located anywhere you want
2. Add a GetProperty service which gets the value of the DirtyFlag in the mashup.
3. In your mashup, add a Validator, configure an Input Parameter called "DirtyFlag", and type boolean. In the expression write "DirtyFlag == true". Check the AutoEvaluate checkbox.
4. Set/bind the Validator input parameter value to the value of the DirtyFlag property from the GetProperty service.
5. Bind the Autorefresh event to the GetProperties service.
Explanation: untill now, we make sure that the True event of the validator fires each time when the DirtyFlag property is set to true.
6. Bind the True event of the Validator to the Query type services
7. Create a new service (located anywhere you want) that sets the DirtyFlag property to true. Let's call this service "ResetDirtyFlag"
8. Add the new Service in the mashup
9. Bind the ServiceInvokeCompleted event of the Query service to the ResetDirtyFlag service
10.Done? Not quite yet!
11. Now you must make sure you also set the DirtyFlag property (we still didn't do that yet). Ideally you should do this where you add/update rows to that datatable/stream/infotable etc.
12. Now it's done
So, we have now lots of requests only for small amounts of data (the GetProperties), and only when we see lots of data.
Constantine,
It would be best if you could avoid transferring data 90% of the times if you don't need it; however, this might not be possible in case it's a third party service that doesn't provide caching or boolean state change information.
In this case you should write a proxy thing implementing a service (e.g. Query) that calls the remote service, persists the data locally only if it has changed (LocalData property), and sets a boolean property to true if the data has changed.
At this point you implement an HasChanged service in the proxy (that returns the value of the boolean property) as well as a GetData service to read the local copy of the data.
On the mashup side, you do the following:
Core to this approach is the use of a Validator that acts like a diode: if the boolean property is true, then the validator fires its True event, which calls the GetData service; if the boolean property is false, then the Validator does nothing: the GetData service is not called, and the widget is not refreshed.
HTH,
Alessio
Hello Gentlemen,
Thank you all for good suggestions! All of that definitely makes sense.
My situation was a bit exotic:
I figured out that in my case a simple browser-side cache would be the most efficient, but I couldn't find an elegant solution to keep this InfoTable somewhere in the browser and compare it with the returned value.
At the end of the day the solution was really dumb -- we just recreated the repeater mashup and for some reason it stopped blinking. I still don't know why, now when we update the number of repetitions it redraws instantaneously, without erasing the old image, so if the number didn't change -- I wouldn't see the refresh.
But if I had to do this "cache", I would probably go with the timestamp-based solution for checking the changes, similar to what Vladimir and Alessio suggested. I will mark Vladimir answer "correct", because he was the first
Thank you for an interesting discussion!
Regards,
Constantine
Alessio Marchetti Vladimir Rosu I have the same problem , I wanted to update "Counter" field on Mashup while my "SetCount" service invoke from outside Thingworx ( from Java code ).
after invoking service i wanted to update Counter on Mashup also without refreshing all mashup data because it causing so much leggy.
how i can archived this.. please help