2017-10-10 25 views
0

J'ai un problème récursif avec un abonnement à changement de variable. Comme vous pouvez le voir, j'utilise la convetion d'Aurelia pour écouter les changements de variable. Et quand la valeur de cette variable est modifiée par l'utilisateur, je veux ajouter '2017' à la fin de celui-ci. Cependant, quand je change la valeur de l'année, cela provoque un appel récursif à cette même fonction. Et il continue à appeler cette même fonction jusqu'à ce que l'application se bloque.L'observateur de variables aurelia continue à s'appeler récursivement

Y a-t-il un moyen pour Aurelia de l'empêcher? Merci

Répondre

1

yearChanged est appelée chaque fois que la propriété year change. Vous modifiez la propriété year à l'intérieur du rappel yearChanged, vous avez donc créé une boucle infinie. Vous devez noter que la propriété year a déjà été définie lorsque yearChanged est appelée (c'est ce que le rappel est yearChanged et non yearIsAboutToChange).

Je pense qu'il y aurait un certain nombre de façons de résoudre ce problème. Le plus simple serait probablement de créer une propriété supplémentaire sur votre viewmodel. Une propriété peut être liée et peut être utilisée pour la détection de changement et l'autre peut être utilisée à des fins d'affichage.

@bindable year; 
displayYear; 

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

Vous pouvez aussi court-circuiter le cycle:

@bindable year; 

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

Encore une fois, sans plus de contexte, il est difficile de dire, mais à partir du code que vous avez présenté, il est tout à fait possible qu'un Value Converter est ce que tu veux vraiment bien.

0

Si c'est juste à des fins de représentation, je voudrais aller avec un convertisseur de valeur. Il y a toujours des cas légitimes où vous auriez besoin de faire ceci (emballage d'un composant tiers). Ensuite, vous pouvez effectuer les opérations suivantes:

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; } 
    // ... 
    } 
} 

Les tâches sont exécutées synchroniquement - ils sont pas attendirent pour terminer un async travail.