Reputation: 4011
i'm building an application using Angular 4, I have a component with the following template:
<input
[value]="myService.myValue"
>
where myService is a service injected into the component:
@Injectable()
export class MyService {
public myValue: string; // I could use an RxJS observable/Subject here
}
I need to add a directive (or something) who is listening for changes of myValue and change the color of the input text.
How can I do it? Any ideas?
Thanks!
Upvotes: 1
Views: 3102
Reputation: 31833
A subject is way overkill for what you're talking about. In general, are reactive subject should be used sparingly.
You can accomplish what you want with a simple get
accessor
export class MyService {
myValue_: string;
get myValue() {
return this.myValue_;
}
}
If you want the value to flow in the other direction as well you can add a set
accessor although that would be best avoided since having a view right into your service class would be bit nasty.
Upvotes: 0
Reputation: 4011
I found a solution:
<input [myDirective]="myService.parameter" myServiceValue="{{myService.value}}" ... >
@Directive({
selector: '[myDirective]'
})
export class parameterDirective implements OnInit, OnChanges {
@Input('myDirective') parameter: parameter;
@Input() myServiceValue: string;
constructor(private el: ElementRef, private renderer: Renderer) {
}
ngOnInit(): void {
}
ngOnChanges(changes: SimpleChanges): void {
switch (this.parameter) {
case parameter.EnumValue:
this.renderer.setElementClass(this.el.nativeElement, "my-class", changes.myServiceValue.currentValue > 100);
break;
default:
}
}
}
Upvotes: 0
Reputation: 8859
You can use ngClass or ngStyle as following
<input [value]="myService.myValue"
[ngStyle]="{'color': myService.myValue === 1 ? 'red' : 'blue'}">
or with ngClass
<input [value]="myService.myValue"
[ngClass]="{'color-red': myService.myValue === 1, 'color-blue' : myService.myValue === 2}">
Check this plnkr
https://plnkr.co/edit/2IAxwnXOaWS4TUL7aov0?p=preview
Upvotes: 0
Reputation: 20005
Create a shared service so when myValue
changes you listen to it and you apply whatever logic you want.
Service:
@Injectable()
export class MyService {
updateMyValue$: Observable<any>;
private updateMyValueSubject = new Subject<any>();
constructor() {
this.updateMyValue$ = this.updateMyValueSubject.asObservable();
}
updateVal(newVal) {
this.updateMyValueSubject.next(newVal);
}
}
Component that changes the value:
this.myService.updateVal('new value');
Component that listens to the value's change:
this.myService.updateMyValue$.subscribe(
(newVal) => {
this.inputValue = newVal; // I called `inputValue` to the variable that will contain the value of the input. It should be initialized.
// Here we can apply our own logic such as change color, hide some DOM elements or whatever we need to do
}
);
Explanation:
The first component is sending the new value to the service, in our case "new value"
.
The second component is subscribed to this Subject
and as soon as next()
is triggered it will receieve the new data. In other words, this component is listening to updateVal()
function and as soon as it's triggered it will receive the data.
It's a very solid and practical way to communicate between components.
Upvotes: 1