2017-10-10 15 views
0

私は可変変更サブスクリプションで再帰的な問題があります。aurelia変数オブザーバは再帰的に自身を呼び出し続けます

@bindable year; 

yearChanged(newVal, oldVal) { 
    if (newVal) { 
    this.year = this.year + '2017'; //just an example 
    } 
} 

これは、変数の変更をリッスンするためにAureliaのコンビネーションを使用しています。そして、その変数の値がユーザーによって変更されたとき、私はそれの最後に '2017'を追加したいと思います。

しかし、私は年の値を変更すると、同じ関数への再帰呼び出しが発生します。そして、アプリケーションがクラッシュするまで、同じ関数を呼び出し続けます。

これをやめることをアウレリアに止める方法はありますか?ありがとう

答えて

1

yearChangedyearプロパティが変更されるたびに呼び出されます。 yearChangedコールバック内のyearプロパティを変更しているため、無限ループが作成されています。 yearChangedが呼び出されたときにyearプロパティが既に設定されていることに注意してください(これはコールバックがyearChangedで、yearIsAboutToChangeではありません)。

私はこれを解決する方法がいくつかあると思います。最も簡単なのは、あなたのビューモデルに追加のプロパティを作成することでしょう。 1つのプロパティはバインド可能であり、変更検出に使用でき、もう1つは表示目的で使用できます。

@bindable year; 
displayYear; 

yearChanged(newVal, oldVal) { 
    if (newVal) { 
    this.displayYear = this.year + '2017'; //just an example 
    } 
} 

ます。また、ショートサイクルができます

@bindable year; 

yearChanged(newVal, oldVal) { 
    if (newVal && oldVal + '2017' !== newVal) { 
    this.year = this.year + '2017'; //just an example 
    } 
} 

は再び、より多くのコンテキストなしでそれを伝えるのは難しいですが、あなたが提示したコードから、Value Converterであることを十分に可能ですあなたが本当に欲しいもの。

0

単なる表記の目的のために、私はバリューコンバータを使用します。 これを行う必要がある場合(サードパーティ製のコンポーネントをラップする)の合法的なケースがあります。そして、次の操作を実行できます。

import {TaskQueue} from 'aurelia-task-queue'; 
import {inject} from 'aurelia-dependency-injection'; 

@inject(TaskQueue) 
class MyCustomElement { 
    constructor(queue) { 
    this.queue = queue; 
    } 

    setPropertyOfInterestInternally(value) { 
    this.internalSet = true; 
    // setting the property here will make the 
    // the underlying mechanics to enqueue a task 
    // on the micro task queue - to invoke the change handler 
    // it will not be invoked in the current call stack 
    this.propertyOfInterest = value; 
    // we schedule another task on the micro task queue 
    // the arrow function(task) will run after the change handler 
    this.queue.queueMicroTask(() => this.internalSet = false); 
    } 

    propertyOfInterestChanged() { 
    // if the set is internal => skip 
    if (this.internalSet) { return; } 
    // ... 
    } 
} 

タスクを同期を実行している - 彼らは非同期作業を完了するために待たないです。

関連する問題