2017-07-18 2 views
0

so habe ich diese Situation:Asynchronous Abrufen von Daten und Rendering in ExtJS mit Ajax

renderer: function(value, grid, record) { 
        var testAjax = function(callback) { 
        Ext.Ajax.request({ 
         url: appConfig.baseUrl + '/api/users/' + record.getData().id + '/jobRoles', 
         method: 'GET', 
         success: function(result) { 
         callback(result) 
         }; 
        }); 
        }; 
        return testAjax(function(result) { 
        try { 
         result = JSON.parse(result.responseText); 
        } catch(e) { 
         return ''; 
        } 
        result = result.data; 
        var roles = _.map(result, function(jRole) { 
         console.log(jRole); 
         return jRole.name; 
        }).join(','); 
        console.log("Roles: ", roles); 
        return roles; 
        }); 
       } 

Was ich erreichen wollte, das ist, wenn ich ein bestimmtes Feld zu machen habe, ich einen Anruf auf meinen Loopback-Endpunkt machen, rufen Sie einige Daten über eine Beziehung ab, ordnen Sie sie mit einem Zeichen "," zu und geben Sie die verknüpfte Zeichenfolge zurück, um sie anzuzeigen.

Aber ich denke, ich habe ein paar Probleme mit Rückrufen hier, da ich das Ergebnis überhaupt nicht sehe, als ob die Funktion zurückgibt, bevor der Rückruf aufgerufen wird (also zeigt nichts, was ich vom Server abgerufen).

Ich habe versucht, hier und da zu suchen, und das ist das Beste, was ich kam.

Wie kann ich die Variable "roles" zur übergeordneten Funktion zurückkehren? Wie richte ich meine Rückrufe richtig ein?

Grüße

+0

Wäre es nicht besser, alle Jobrollen in einem Geschäft zu laden und dann nachzuschlagen? – scebotari66

Antwort

1

Sie können nicht und nicht den Renderer mit Ladeoperationen und asynchrone Rückrufe verwenden sollten. Der Renderer kann Dutzende Male für denselben Datensatz aufgerufen werden, wenn Sie die Rasteransicht filtern oder sortieren oder die Rasteransicht aktualisieren. Sie möchten alle Informationen erhalten, die für die Anzeige im Raster in einem einzigen Anruf erforderlich sind. Daten, die Sie in einem einzelnen Anruf nicht erhalten, sollten nicht im Raster angezeigt werden. Sie möchten den Endpunkt 1000 Mal für 1000 Datensätze nicht aufrufen, da selbst wenn jeder Aufruf nur 60 ms benötigt, dies eine volle Minute ist.

Das heißt, wenn Sie wirklich haben, weil Sie nicht die Endpunkte ändern können und die Rollen müssen angezeigt werden, können Sie wie folgt vorgehen:

dataIndex: 'MyTempRoles', 
renderer: function(value, grid, record) { 
    if(value) return value; // show the loaded value if available 
    else { // no value loaded -> load value 
     Ext.Ajax.request({ 
      url: appConfig.baseUrl + '/api/users/' + record.getData().id + '/jobRoles', 
      method: 'GET', 
      success: function(result) { 
       try { 
        result = JSON.parse(result.responseText); 
        result = result.data; 
        var roles = _.map(result, function(jRole) { 
         console.log(jRole); 
         return jRole.name; 
        }).join(','); 
        record.set("MyTempRoles", roles || " "); // put the loaded value into the record. This will cause a grid row refresh, thus a call to the renderer again. 
       } catch(e) { 
       } 
      } 
     }); 
    } 
} 

Dies wird das Backend im ersten Aufruf rufen Renderer und füllt asynchron die Temperaturvariable des angezeigten Datensatzes. Wenn die Variable temp gefüllt ist, zeigt der Renderer den Wert aus der Variablen temp automatisch an.

+0

Das hat wie ein Zauber funktioniert! Auch danke für die Vortrag mich über Renderer-Ereignis, ich dachte, es wurde einmal auf dem Display aufgerufen, wird mehr in es aussehen :) –

+0

Öffnen Sie https://fiddle.sencha.com/#view/editor&fiddle/23nu, öffnen Sie die Browser-Konsole und einfach Scrolle das Raster nach unten und oben. Sie werden feststellen, dass der Renderer wirklich oft aufgerufen wird. – Alexander