In Angular 2 I'm using ngStyle
to change the background and text color of a button. My ngStyle
is using a function as it's expression.
<input type="button" value="Go" [ngStyle]="getButtonStyle()">
Here is the function:
getButtonStyle() {
console.log("Hit the function");
if(this.serialListCount == 1) {
console.log("Option #1 triggered")
return { background: ''#cc0000', color: 'white' };
}
else if(&& this.serialListCount > 1) {
console.log("Option #2 triggered")
return { background: '#23b900', color: 'black' };
}
}
I noticed the function is being called hundreds of times within a short period of time on the form. The guys who wrote the initial code are using ngCompleter
which is a type-ahead component used to help the user complete their search criteria on other fields and those changes to the data set is what I am trying to keep track of and do things style wise based on the list having "one" vs "more than one" items in it's collection.
The property that I am checking to decide if I should run the If
or If Else
block is a .length
property on a list of serial numbers. That list is an observable under the hood, I know because when I look at the property it is getting the serialNumberList.length
of, it is defined as such:
serialNumberList: CompleterData;
If we F12
on that completerData
we see this:
import { EventEmitter } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { CompleterItem } from "../components/completer-item";
export interface CompleterData extends Observable<CompleterItem[] | null> {
dataSourceChange?: EventEmitter<void>;
search(term: string): void;
cancel(): void;
convertToItem?(data: any): CompleterItem | null;
}
I get the length of the collection and set it inside of my GetSerialNumbers()
method like so:
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Rx';
//...
import { CompleterService, CompleterData } from 'ng2-completer';
//...
@Component({
//...
})
export class XxxDetailComponent implements OnInit {
serialNumberList: CompleterData;
serialListCount: number = 0
constructor(private completerService: CompleterService) { }
getSerialNumber(): void {
this.commonService.getSerialNumbers(this.getSerialNumberInput)
.then((response) => {
(response && response.length == 1)
? this.xx.serialNumber = response[0].serialNumber
: this.serialNumberList = response;
//THIS IS WHERE I GET THE LENGTH OF THE LIST
this.serialListCount = response.length;
}
Since this method is being called so many times it must be because I have set it up to evaluate a property that is connected to an observable. And since that list it is representing the length of changes with every focus or few keystrokes in other input fields, that data source has a lot of activity modifying it's number of items contained.
So far this is nothing that is going to production, I want a better grasp of Angular and I'm pulling rookie moves as I have been out of front end for two years and just getting back into Angular. Observables are new to me, I was unaware what I was doing until I slapped a debugger in the function.
So I have asked myself..
Is this function and the change to the style happening so often a real issue? I could keep track of what evaluation that triggers the style change in the else statement that is being set and not set it again if it's already set, but it would still hit the method just as many times, just not set the background over and over with the same value. Someone mentioned change detection, that sounds promising. Would it be better to check a value that is somehow not connected to that observable, but gets updated with the correct data list length on a much less basis? Is this normal to evaluate something that changes so often and will I see performance issues from this?
Actual Question: What is the more desirable way to structure this method that returns the styles and is there something I can do with an Rx Pattern that would help?
A good link or resource if answered would be awesome for me to help understand more deeply.