Remove state style after certain delay in Angular - angular-animations

I'm building Angular 13 application where redis database is pushing its changes, and I want certain numeric values to be animated (styled) depending on whether the value is increasing or decreasing. And after certain delay (let's say 3secons) I would like state style to be removed.
What I have until now is:
animations: [
trigger('change', [
state('increase', style({ backgroundColor: 'rgb(3, 190, 3)' })),
state('decrease', style({ backgroundColor: 'red' })),
state('',style({})),
transition('* => *',animate(10)),
])
]
HTML part where I use the trigger, is default one:
<div [#change]="getState()" class="col-4 p-0">{{tennisWorkerObject.konecenTip.home | number:"1.2-2"}}</div>
getState() function have background logic to return either of the 3 states stated in animation definition above. But, its executed just once, after redis change notification.
And it's working properly, but after everything I've tried, I can't remove state style after above-mentioned 3 seconds.

Related

How to redraw whole table after changing theme?

I'm using ag-grid 29 in React. I can change the style from Balham to Alpine on the fly. My problem: Neither the heard rows nor the data rows are then tall enough. Is it possible to accomplish this?
Here's the "before" - my table in Balham:
Here's the "after" - my table in Alpine. Please note the text overflowing the row height:
Here are the methods I call after the style change:
gridApi.refreshHeader()
gridApi.refreshCells()
gridApi.redrawRows()
gridApi.sizeColumnsToFit()
The official demo appears to destroy and recreate the entire grid when you change the theme dropdown, by passing a new React key to the grid component:
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const theme = params.get('theme') || 'ag-theme-alpine';
setGridTheme(theme);
}, []);
<div id="myGrid" className={gridTheme}>
<AgGridReactMemo
key={gridTheme}
// ...
/>
</div>
Actual users probably won't change the theme very often, so it's likely not worth putting effort into doing this elegantly. It may be possible to fix everything by calling various functions, but I didn't look in to it.

Avoiding rerendering of my custom items in a Flat List

I created a custom item for my Flat List which shows the name and the image ( retrieved by his url) of a certain product. The user can filter this products by their names, and the new filtered data is passed again to the Flat List. The problem is that whenever I filter the data, Flat List re-renders every custom item, so the Image components inside have to download the pic again, causing a flickering effect. This is an approximate example of what I mean:
function test(){
initialData=[
{
text: 'product A',
image: 'https://picsum.photos/200/300',
id: 1
},
{
text: 'product B',
image: 'https://picsum.photos/200/300',
id: 2
},
{
text: 'product C',
image: 'https://picsum.photos/200/300',
id: 3
},
]
const [filteredData, setFilteredData] = useState(initialData);
const handlePress = () =>(
setFilteredData(filterData(data)); // Filter data by some parameters
)
const renderItem = (props) => {
return(
<View>
<Image>{props.text}</Image>
<Text source={{uri: props.image}}></Text>
</View>
)
}
return(
<>
<Button onPress={() => handlePress()}></Button>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={renderItem}
/>
</>
)
}
first must to say in order to avoiding unnecessary rendering data you are be able to use useMemo and useCallback methods (in functional programming) for memorizing your variables and your functions (check hooks React hooks documents). some procedures can help you for improving your code:
Don't put the static data inside your function, for example put initialData outside of your test function or memorize it by useMemo.
Don't use inline function inside components and as far as possible memorize them.
You can create independent component for your FlatList item and memorize it by memo then use them or memorize renderItem inside your test function.
For use image in your app (specifically when you have large numbers of image) use react-native-fast-image that help you avoiding to re-rendering images by caching them.

React-Virtualized ScrollSync: How to set an initial scrollTop value?

I'm using the react-virtualized ScrollSync component to sync the scrolling of a couple fixed headers — very similar to the example in the docs.
My question: is it possible to provide an initial scrollTop value to ScrollSync (or its children)? I realize that the better way to do this would be through use of scrollToRow on the Grid component that controls the scroll position — for what it's worth, I am using scrollToColumn for this purpose. But because, vertically, I'm only rendering one very tall cell, scrollToRow doesn't provide the fidelity needed.
I do realize that this is a slightly bastardized use of a grid component, but it all works quite nicely as a horizontal, infinitely loading scroller, while allowing me to re-use an existing component. If I could just set an initial scrollTop, I'd be golden.
Thanks.
Unfortunately this is not currently supported without a bit of a hack.
First, the reason for the hack: Scroll offsets flow in one direction with ScrollSync (main Grid to synchronized Grids). This means that even if ScrollSync accepted default left/top offsets as props- they would get overridden by the first render of the main Grid. I think this is probably the right thing to do to avoid ugliness inside of react-virtualized.
However you could work around it in application code like this if you wanted to:
class YourComponent extends Component {
render () {
// These are arbitrary
const defaultScrollLeft = 300
const defaultScrollTop = 500
return (
<ScrollSync>
{({ clientHeight, clientWidth, onScroll, scrollHeight, scrollLeft, scrollTop, scrollWidth }) => {
if (!this._initialized) {
scrollLeft = defaultScrollLeft
scrollTop = defaultScrollTop
this._initialized = true
}
return (
<div>
<Grid
{...otherSyncedGridProps}
scrollLeft={scrollLeft}
/>
<Grid
{...otherMainGridProps}
onScroll={onScroll}
scrollLeft={defaultScrollLeft}
scrollTop={defaultScrollTop}
/>
</div>
)
}}
</ScrollSync>
)
}
}

Multiple qTip2 on the same element

Calling .qtip twice on the same element erases the previous qtip. Is it possible to have 2 styles of qtip on the same element (one is right click, one is mouse over)
You cant have 2 on the same element but you can wrap the element in a span and call qtip on that with a different trigger.
I just upvoted Bruian's answer as I have tried the other technique that I found through Googling which says to create a qtip and to add removeData('qtip') before adding another one :
$('.selector')
.qtip() // tooltip 1
.removeData('qtip') // remove it's data
.qtip(); // tooltip 2
This technique will work for simple cases, but you are setting yourself up for a lot of problems down the line with duplicate ids and other issues.
For those still interested using one description for multiple item. You can use this method:
1) Make one div with all the description item you want.for example:
<div id='description' class='describe_content' style='display:none;'>
<div id='test'>this is description</div>
<div id='test2'>teeest</div>
</div>
2) Use the following code for the qtip. You can see the comment on what each item do.
$(document).on('mouseover','input ,select ,dl , .dropdown2 .mutliSelect li',function(event)
{
string = $("#test2");
$(this).qtip({
overwrite: true, //to allow it the same item be paste to other part.
position: {
my: pos[pos_c+3], // Position my top left...
at: pos[pos_c], // at the bottom right of...
target: $(this) // my target
},
content: {
text: string, // the text
},
show:{
event: event.type, //use the same show event as the one that triggered
ready: true //show the tooltip as soon as it's bound.
},
'font-size': 16
},event);// have to pass event as second parameter, because qtips positioning
}
Note that the position is just a extra option, you could remove it if you want.

Ember.js flashes list contents when adding models - how do I fix?

I am using Ember.js to build an application that uses Server-Sent Events to add and update a controller that implements paging. The full implementation of the controller is listed below.
App.endpointsDisponiblesClass = Ember.ArrayController.extend({
loading: true,
completeList:[
/*
App.Endpoint.create({
id: 1,
id_manufacturer: 1,
id_model: 1,
mac_address: '00:11:22:33:44:55',
last_known_ipv4: '10.0.0.1',
last_scanned: '2012-12-31',
last_configured: null
}),
*/
],
content: [],
offset: null,
limit: 10,
displaySlice: function(offset) {
if (offset >= this.completeList.length)
offset = this.completeList.length - 1;
if (offset < 0) offset = 0;
offset = offset - (offset % this.get('limit'));
if (this.get('offset') == null || offset != this.offset) {
var slice = this.completeList.slice(offset, offset + this.get('limit'));
this.set('offset', offset);
this.set('content', slice);
}
},
displayStart: function() { this.displaySlice(0); },
displayPrevious: function() { this.displaySlice(this.offset - this.limit); },
displayNext: function() { this.displaySlice(this.offset + this.limit); },
displayEnd: function() { this.displaySlice(this.completeList.length); },
startPosition: function() {
return this.get('offset') + 1;
}.property('offset'),
endPosition: function() {
var pos = this.get('offset') + this.get('limit');
if (pos > this.completeList.length)
pos = this.completeList.length;
return pos;
}.property('offset', 'limit'),
displayRefresh: function() {
console.debug('displayRefresh');
var offset = this.get('offset');
this.set('offset', null);
this.displaySlice(offset);
}.observes('completeList.#each')
});
App.endpointsDisponibles = App.endpointsDisponiblesClass.create();
The completeList element contains the full list of elements I want to page through, with one of them listed as a comment. In my implementation, I perform the paging by assigning slices of the full list to the 'content' element of the ArrayController subclass. Additionally there are some helper methods that get invoked from various views that display buttons for Next, Back, and so on.
The template fragment that renders the model list looks like this:
{{#view tagName="tbody"}}
{{#each App.endpointsDisponibles}}
<tr class="neo-table-data-row">
<td class="neo-table-data-row">{{view Ember.Checkbox checkedBinding="isSelected"}}</td>
<td class="neo-table-data-row">{{mac_address}}</td>
<td class="neo-table-data-row"><a target="_blank" {{bindAttr href="adminUrl"}}>{{last_known_ipv4}}</a></td>
<td class="neo-table-data-row">{{name_manufacturer}}</td>
<td class="neo-table-data-row">{{view Ember.Select
contentBinding="modelSelect"
optionValuePath="content.id_model"
optionLabelPath="content.name_model"
valueBinding="id_model"
disabledBinding="App.endpointScanController.scanInProgress"}}</td>
</tr>
{{else}}
<tr class="neo-table-data-row">
<td class="neo-table-data-row" colspan="7">No endpoints have been discovered or loaded.</td>
</tr>
{{/each}}
{{/view}}
I prepare an EventSource with an onmessage handler that parses a JSON message from the server, and updates the completeList, by adding/updating/removing models as required on completeList. Since I observe completeList.#each with displayRefresh(), the page slice gets updated in case I view the last page and a model is added, or if one of the viewed models is removed. So far, it works perfectly.
The problem is that half of the time a message triggers an insert, the re-rendering of the template is awfully visible to the user. The template gets emptied, remains empty for about a fraction of a second, and is then refilled with the proper contents. The other half of the time, the template contents get smoothly updated without emptying and refilling, which is what I want. The SSE message stream is bursty - it is idle for a few seconds, then fires some 5 to 6 messages in less than a second, then the cycle repeats. The ugly rendering has been observed in both Firefox and Google Chrome.
In Firefox, I have installed Firebug, and I can invoke the controller methods from the console. When I do that, they behave exactly as in the SSE case. Sometimes the refresh is smooth, and sometimes the emptying and refilling of the template is visible.
What can I do to ensure that the template rendering is consistently smooth?
I'm having a similar problem - this question is the only result that came up in my google searches for "arraycontroller flash".
The problem comes about when I reset the model of an array controller:
#set 'model', message
The interesting thing is that I've got an almost-identical application that I've built using knockout - and that has no flashing / refresh issues.
I stumbled across this post: Mitigating a flickering UI when refreshing content in Ember and ended up wrapping my update in an Ember.run function, which solved the flickering, but it still seems wrong to me.
Ember.run =>
#set 'model', message
[ deleted complete red herring ]
As of now it seems that the correct path is to wrap in Ember.run - ugly as all hell, but it does solve the immediate problem. My guess is that Ember isn't quite as optimized / fast as knockout is, or Ember has a bug with the queuing of the updates. Hopefully it will improve as time goes on.
EDIT 7/23/13 -
I realized after I wrote this that Ember is completely right, and I was completely wrong. (and the knockout thing is incidental)
As described here: http://emberjs.com/guides/understanding-ember/managing-asynchrony/ it seems that Ember uses events to bundle updates together - effectively wrapping an event handler in Ember.run
But in my case (and I think yours) we're calling an ajax method, which is asynchronous. The callback (or promise - same problem) happens after the Ember event has fired and returned. So Ember has no way of knowing that it needs to queue up the updates.
Still not sure that the "correct" solution is to wrap it in Ember.run - the docs (http://emberjs.com/api/classes/Ember.run.html) seem to indicate that it's not right, but the docs also push towards Ember Data, which wouldn't have this problem.
Guess I need to read up on Ember's runloop some more.

Resources