Angular2 knockout version computed observed

I am currently working on porting the code that I wrote from Knockout to Angular2. I really like the design of the calculated observables in the knockout, which means that the results of this function are only calculated when it depends on the changes.

I know that I can use a function in angular, and it will only update the view when the results change (although they will calculate the results many times), but my calculations do sorting, so I only want the work to be done when the inputs really are changing.

I found the links below that explain how to do this with angularjs, but I'm not sure how to translate this to angular2 (typescript)

http://www.jomendez.com/2015/02/06/knockoutjs-computed-equivalent-angularjs/ KO. Computer equivalent in angular / Breeze Initializer

+4
source share
2 answers

I would consider getter if you are using TypeScript. You can also use your ChangeDetectionStrategy.OnPush component to make sure that the binding is evaluated only when one of the properties changes. Here is Plunker: https://plnkr.co/edit/PjcgmFCDj8UvBR7wRJs2?p=preview

import {Component,ChangeDetectionStrategy} from 'angular2/core'

@Component({
  selector:'person',
  template:`<div>
              <div>
                  First Name
                  <input [(ngModel)]="firstName">
              </div>
              <div>
                  Last Name
                  <input [(ngModel)]="lastName">
              </div>

              {{fullName}}
          </div>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class Person{
  firstName = '';
  lastName = '';

  get fullName(){
    return this.firstName + ' ' + this.lastName;
  } 
}
+8
source

The closest analogue ko.observableis Subjector even BehaviorSubject, and for ko.computedyou can useObservable.combineLatest

:

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());
  }
}

, , , :

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
    });
  }
}

, FormControl, valueChanges, .

| async ,

+3

All Articles