2016-04-01 10 views
4

現在、ノックアウトからAngular2に書き込んだコードを移植しています。私はノックアウトの計算されたオブザーバブルの構築が本当に好きです。つまり、その関数の結果は、変化に依存するオブザーバブルが計算されたときにのみ計算されます。ノックアウトの計算された観測値のAngular2バージョン

私は角度の関数を使うことができますが、結果が変わると(結果は何度も計算されますが)、ビューを更新するだけですが、計算が並べ替えを行っているので、実際に入力が変化したときに作業する必要があります。私は考えるでしょう

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

答えて

8

を私は以下のリンクがangularjsでそれを行う方法を説明したが、私はangular2にそれを変換するかどうかはわかりません(typescriptです)

TypeScriptを使用している場合はゲッターです。また、コンポーネントがChangeDetectionStrategy.OnPushを使用して、プロパティの1つが変更された場合にのみバインディングが評価されるようにすることもできます。ここで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; 
    } 
} 
+2

に対処していない場合は、この機能の内容はコンピュータだけであることを確認していない場合、入力の変化の一。 getter関数が何らかの計算集約的な作業(オブジェクトの大きなリストの並べ替えなど)を行っている場合、これは引き続き非効率的です。あなたは提供されたplunkrでこれを見ることができます。 –

3

ko.observableの最も近いアナログはSubjectかさえBehaviorSubjectで、ko.computedのためにあなたがここにObservable.combineLatest

を使用することが一種のHello Worldの例:

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あなたは常にあなたのストリームを購読することができますテンプレート内の配管と、それらのコンポーネントのプロパティ

関連する問題