2016-07-26 9 views
0

Ich habe benutzerdefinierte Tabs-Funktionalität, aber nach dem Update von Aurelia auf rc-1.0.x, gibt es ein Problem mit Auflistungsdaten von @children Dekorator.Aurelia: Wie kann man verfolgen, ob @children-Elemente geladen sind?

Mein Code sieht in etwa so aus: import {inject, customElement, children} aus 'aurelia-framework';

@customElement('tabs') 
    @inject(Element) 
    @children({name:'tabs', selector: "tab"}) 

    export class Tabs { 
     activeTab = undefined; 

     constructor(element) { 
     this.element = element; 
     } 

     attached() { 
     console.log(this.tabs); // Return undefined on promise resolve!!! 
     this.tabs.forEach(tab => { 
      if (tab.active) { 
      this.activeTab = tab; 
      } 

      tab.hide(); 
     }); 

     this.activeTab.show(); 

     } 

Auf dem ersten Last alles funktioniert ganz gut, und this.tabs ist ein Array von Elementen, wie erwartet.

Als nächstes, wenn ich eine Server-Anfrage, wenn Versprechen ist gelöst this.tabs Konsole Protokolle undefiniert.

Wenn ich Timeout einstellen behebt das Problem, aber ist das der richtige Weg?

Auch bemerkte ich in dem HTML-Code, dass die repeat.for Anweisung ausgeführt wird, die mir einen Hinweis geben, dass this.tabs mit einem gewissen Verzögerung empfangen wird, nachdem die angeschlossene Funktion behandelt wird.

Die html:

<template> 
    <ul class="nav nav-tabs m-b-1"> 
    <li repeat.for="tab of tabs"> 
     <a href="#" click.trigger="$parent.onTabClick(tab)"> 
     ${tab.name & t} 
     </a> 
    </li> 
    </ul> 
    <slot></slot> 
</template> 

So ist es eine Möglichkeit, dass die Arbeit mit der Aurelia binden oder an Methoden oder eine elegantere Art und Weise zu machen, anstatt den Wert this.tabs mit einer Timeout-Funktion zu überprüfen?

+0

Wo ist das Versprechen in Ihrem Code gelöst? –

+0

Registerkarten sind Teil eines anderen benutzerdefinierten Elements. Das Versprechen wird in einer anderen Kerndatei gelöst, die wir mit bindEngine verfolgen und das Modell dieses benutzerdefinierten Elements aktualisieren. –

+1

Würde es Ihnen etwas ausmachen, mit gist.run eine schnelle Repro Ihres Problems zu erstellen? Ich habe eine grundlegende Einrichtung für Sie erstellt, um von hier aus zu starten: https://gist.run/?id=cbf7a20cd866d4c2a56ddda80ab26764 Fügen Sie einfach den erforderlichen Code hinzu, klicken Sie auf "Fork to Public Gist" und veröffentlichen Sie den Link als Kommentar. –

Antwort

0

Ich denke, dass dies ein angemessener Anwendungsfall für die Task-Warteschlange sein könnte (aber wenn jemand kenntnisreich anderes denkt, lassen Sie es mich wissen). Ich musste die Task-Warteschlange verwenden, bevor ich auf bindbare Werte innerhalb von attached zugreife, und Ihre Instanz sieht im Grunde gleich aus (außer Sie greifen auf sie unter Verwendung von zu).

Die TaskQueue verschiebt Ihre Logik an das Ende des Verarbeitungsstapels. Theoretisch bedeutet das, dass es darauf wartet, dass Aurelia seine interne Logik für Bindings und möglicherweise Kinderdekorator-Auflösung ausführt und dann Ihren Code ausführt.

Es könnte eine bessere Lösung geben, aber ich habe diese bereits verwendet, um aus einer ähnlichen Situation wie oben erwähnt herauszukommen und muss noch eine bessere Lösung finden, die das Problem behebt, insbesondere beim Zugriff auf dynamische Werte attached.

import {TaskQueue} from 'aurelia-framework'; 

@customElement('tabs') 
@inject(Element, TaskQueue) 
@children({name:'tabs', selector: "tab"}) 

export class Tabs { 
    activeTab = undefined; 

    constructor(element, taskQueue) { 
    this.element = element; 
    this.taskQueue = taskQueue; 
    } 

    attached() { 
    this.taskQueue.queueMicroTask(() =>{ 
     this.tabs.forEach(tab => { 
      if (tab.active) { 
       this.activeTab = tab; 
      } 

      tab.hide(); 
     }); 

     this.activeTab.show(); 
    }); 
    } 
+0

Danke für die Antwort! Wie ich sage, refaktoriere ich die Logik und mache diese Funktionalität viel einfacher. Wie auch immer, was Sie über die taskQueue sagen, wird mir helfen, ein anderes Problem zu lösen. Ich bin auch umhergewandert, gibt es einen Zuhörer, der dies immer erkennt.Registerkarten ist gefüllt, und dann Funktion ausführen, die die Iteration tun wird? Vielleicht etwas, das von repeat.for-Attribut im HTML verwendet wird? –