The closest analogue of ko.observable
is Subject
or even BehaviorSubject
, and for ko.computed
you may use Observable.combineLatest
Here kind of hello world example:
import 'rxjs/add/operator/map';
import {Component} from '@angular/core';
import {Observable, BehaviorSubject} from "rxjs";
@Component({
selector: 'app-root',
template: `<div>
<button (click)="both()">both</button>
<button (click)="first()">first</button>
<button (click)="last()">last</button>
<button (click)="ageNow()">age</button>
<hr />
fullName: {{fullName | async}}
<hr />
age: {{age | async}}
</div>`
})
export class AppComponent {
firstName = new BehaviorSubject(''); // aka this.firstName = ko.observable('')
lastName = new BehaviorSubject('');
age = new BehaviorSubject(0);
fullName = Observable.combineLatest(this.firstName, this.lastName) // aka this.fullName = ko.computed(...)
.do(values => console.log('computed fired'))
.map(values => values.join(' ').trim());
both() {
this.first();
this.last();
}
first() {
this.firstName.next('foo ' + Date.now());
}
last() {
this.lastName.next('bar ' + Date.now());
}
ageNow() {
this.age.next(Date.now());
}
}
And probably you will want to get it working with forms then example will be something like this one:
import 'rxjs/add/operator/map';
import {Component} from '@angular/core';
import {Observable, BehaviorSubject} from "rxjs";
import {FormGroup, FormControl, FormBuilder} from "@angular/forms";
@Component({
selector: 'app-root',
template: `<form [formGroup]="form">
<input formControlName="firstName" />
<input formControlName="lastName" />
{{fullName | async}}
</form>`
})
export class AppComponent {
form:FormGroup;
firstName = new FormControl('');
lastName = new FormControl('');
fullName = Observable.combineLatest(
this.firstName.valueChanges.startWith(''),
this.lastName.valueChanges.startWith('')
).map(values => values.join(' ').trim());
constructor(private fb:FormBuilder) {
this.form = fb.group({
firstName: this.firstName,
lastName: this.lastName
});
}
}
Note that in form example we are watching not for FormControl but for its build in valueChanges
stream, also we define initial value for it.
If you wish not to deal with | async
pipes in templates you always can subscribe to your streams and them component properties