2017-02-08 5 views
-1

Ich habe eine MDC-Autovervollständigung verdrahtet bis zu einer Liste von einem Remote-Datenanruf abgerufen. Ich möchte meine Ergebnisse alphabetisch sortieren, aber orderBy erwartet ein Array und funktioniert nicht mit einem Versprechen.Angular-Material Autocomplete OrderBy Versprechen

SZENARIO 1

Dies ist meine aktuelle Implementierung, die mit dem zurück Versprechen funktioniert, aber orderBy nicht unterstützt.

HTML

<md-autocomplete 
    md-no-cache="true" 
    ng-model-options="{debounce: 250}" 
    md-selected-item="criteria.orderByClientUser" 
    md-search-text="searchText" 
    md-items="item in getClientUsers(searchText)" 
    md-item-text="item" 
    md-min-length="0" 
    placeholder="First Last"> 
    <md-item-template>{{item}}</md-item-template> 
    <md-not-found>No matches found.</md-not-found> 
</md-autocomplete> 

-Controller

$scope.getClientUsers = function(text) { 
    if(!text) return []; 
    text = text.toLowerCase(); 
    return clientUserProfileService.findByName(text); 
} 

ClientUserProfileService

service.findByName = function(name) { 
    return $http.post(searchUrl, name, { withCredentials: true }).then(res => res.data); 
} 

SZENARIO 2

Diese Implementierung wendet die Daten auf den Bereich an, aber die Funktion wird beendet, bevor das Versprechen aufgelöst wird. Daher wird die Autocomplete-Liste nicht aktualisiert.

HTML

<md-autocomplete 
    md-no-cache="true" 
    ng-model-options="{debounce: 250}" 
    md-selected-item="criteria.orderByClientUser" 
    md-search-text-change="getClientUsers(searchText)" 
    md-items="item in userList | orderBy" 
    md-item-text="item" 
    md-min-length="0" 
    placeholder="First Last"> 
    <md-item-template>{{item}}</md-item-template> 
    <md-not-found>No matches found.</md-not-found> 
</md-autocomplete> 

-Controller

$scope.userList = []; 

$scope.getClientUsers = function(text) { 
    if(!text) return []; 
    text = text.toLowerCase(); 
    clientUserProfileService.findByName(text) 
     .then(_.mountP($scope, "userList")); 
} 

ClientUserProfileService

service.findByName = function(name) { 
    return $http.post(searchUrl, name, { withCredentials: true }).then(res => res.data); 
} 

Gibt es eine Möglichkeit, die orderBy zu konfigurieren, um mit dem Versprechen zu arbeiten? Oder gibt es eine Möglichkeit, die Rückgabe von getClientUsers zu verzögern, bis das Versprechen gelöst ist? Diese Abfrage ist extrem schnell, daher weiß ich, dass ich die Servicemethode einfach aufschieben und in ein kleines Timeout umbrechen kann, aber das scheint wie ein Copout zu sein.

Schätzen Sie Ihre Hilfe!

** AKTUALISIERT CODE ** - Still ergibt Versprechen von getClientUsers zurückgegeben wird(), die nicht mit orderBy funktioniert

Error: [orderBy:notarray] 

HTML

<md-autocomplete 
    md-no-cache="true" 
    ng-model-options="{debounce: 250}" 
    md-selected-item="criteria.orderByClientUser" 
    md-search-text="searchText" 
    md-items="item in getClientUsers(searchText) | orderBy" 
    md-item-text="item" 
    md-min-length="0" 
    placeholder="First Last"> 
    <md-item-template>{{item}}</md-item-template> 
    <md-not-found>No matches found.</md-not-found> 
</md-autocomplete> 

-Controller

$scope.getClientUsers = function(text) { 
    if(!text) return []; 
    text = text.toLowerCase(); 
    return clientUserProfileService.findByName(text) 
     .then(function (data) { 
      return data; 
     }); 
} 

ClientUserProfileService

service.findByName = function(name) { 
    return $http.post(searchUrl, name, { withCredentials: true }).then(res => res.data); 
} 

Antwort

2

Szenario # 2 muss ein Versprechen zurück:

//Scenario #2 

$scope.userList = []; 

$scope.getClientUsers = function(text) { 
    if(!text) return []; 
    text = text.toLowerCase(); 
    //vvvv return derived promise 
    return clientUserProfileService.findByName(text) 
     .then(function (data) 
      //_.mountP($scope, "userList") 
      //do something to data 
      //vvvv return data to chain 
      return modifiedData; 
    ); 
} 

Da die .then Methode eines Versprechens fordern eine neue abgeleitete Versprechen gibt, es leicht möglich ist, eine Kette von zu schaffen Versprechen.Es ist möglich, Ketten beliebiger Länge zu erstellen, und da ein Versprechen mit einem anderen Versprechen gelöst werden kann (das seine Auflösung weiter verzögert) ist es möglich, die Auflösung der Versprechen an irgendeinem Punkt in der Kette anzuhalten/zu verschieben. Dies ermöglicht die Implementierung leistungsfähiger APIs.

-- AngularJS $q Service API Reference - Chaining Promises


Um die Daten zu bestellen AngularJS orderBy-Filter:

$scope.getClientUsers = function(text) { 
    if(!text) return []; 
    text = text.toLowerCase(); 
    //vvvv return derived promise 
    return clientUserProfileService.findByName(text) 
     .then(function (data) 
      //_.mountP($scope, "userList") 
      //do something to data 
      var orderByData = $filter("orderBy")(data); 
      //vvvv return data to chain 
      return orderByData; 
    ); 
} 

Weitere Informationen finden Sie AngularJS orderBy Filter API Reference.

+0

Vielleicht irre ich mich, aber wenn ich dies implementiert, gibt die Methode getClientUsers immer noch ein Versprechen zurück, nicht die Daten, die von orderBy nicht unterstützt werden. Dies war die gleiche Situation, in der ich Szenario 1 erlebt habe. Habe ich deine Antwort falsch interpretiert? Ich habe die Frage mit meinem aktuellen Arbeitscode aktualisiert –