Issue: $http issue – Values can’t be returned before a promise is
resolved inmd-autocomplete
Angular MaterialMy Requirement: I need an updated Suggestion List using remote data
sources inmd-autocomplete
Angular Material – Ajax$http
service.
我使用了Angular Material link https://material.angularjs.org/latest/demo/autocomplete中提到的方法
源代码:
场景1:
HTML源代码:
<md-autocomplete flex required md-input-name="autocompleteField" md-no-cache="true" md-input-minlength="3" md-input-maxlength="18" md-selected-item="SelectedItem" md-search-text="searchText" md-items="item in querySearch(searchText)" md-item-text="item.country" Placeholder="Enter ID" style="height:38px !important;"> <md-item-template> <span class="item-title"> <span md-highlight-text="searchText" md-highlight-flags="^i"> {{item.country}} </span> </md-item-template> </md-autocomplete>
AngularJS脚本:
//bind the autocomplete list when text change function querySearch(query) { var results = []; $scope.searchText = $scope.searchText.trim(); if (query.length >=3) { results = LoadAutocomplete(query); } return results; } //load the list from the service call function LoadAutocomplete(id) { var countryList = []; $http({ method: "post",url: "https://www.bbminfo.com/sample.PHP",params: { token: id } }) .success(function (response) { countryList = response.records; }); return countryList; }
场景2:
HTML与AngularJS源代码:
<!DOCTYPE html> <html> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css"> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script> <!-- Angular Material Library --> <script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script> <body> <div ng-app="myApp" ng-controller="myCtrl"> <p>Person to Select:</p> <md-autocomplete ng-disabled="isDisabled" md-no-cache="noCache" md-selected-item="selectedItem" md-search-text-change="searchTextChange()" md-search-text="searchText" md-selected-item-change="selectedItemChange(item)" md-items="item in Person" md-item-text="item.Name" md-min-length="0" placeholder="Which is your favorite Person?"> <md-item-template> <span md-highlight-text="ctrl.searchText" md-highlight-flags="^i">{{item.country}}</span> </md-item-template> <md-not-found> No Person matching "{{searchText}}" were found. </md-not-found> </md-autocomplete> <br/> </div> <script> var app = angular.module('myApp',['ngMaterial']); app.controller('myCtrl',function ($scope,$http,$q) { $scope.searchText = ""; $scope.Person = []; $scope.selectedItem = []; $scope.isDisabled = false; $scope.noCache = false; $scope.selectedItemChange = function (item) { alert("Item Changed"); } $scope.searchTextChange = function () { $http({ method: "POST",params: { token: $scope.searchText } }) .success(function (response) { $scope.Person = response.records; }); } }); </script> </body> </html>
在场景1中,我使用该函数来获取已过滤的列表md-items =“querySearch(searchText)中的项目”.但是在场景2中,我使用了$scope变量md-items =“item in Person”
请参考快照
快照1:
在这里,我正在寻找印度人,但它显示了印度的结果.我在Firefox浏览器Firebug中调试了这个问题,看到上面显示的快照1,请求是通过POST方法为搜索词indian发送的,我得到了一个匹配项作为JSON对象的响应成功,这显示在底部SnapShot 1
The issue I find out in this case,the Values can’t be returned before
a promise is resolved
我试过的步骤:
案例1:我在UI md-items =“item in Person | filter:searchText”中使用了AngularJS过滤器,它提供了先前获取的远程数据的过滤列表,而不是当前获取的远程数据.在Backspacing文本框中的字符时,它会显示不正确的建议列表.
案例2:我尝试通过在$http服务中调用$scope.$apply()来更新UI中的更改,但它失败了.因为$http服务默认调用$scope.$apply(),显示它会抛出一个错误错误:[$rootScope:inprog] ….最后在这次尝试中我失败了.
情况3:我在函数中创建了一个函数,我手动调用$scope.$apply(),在我手动推送的函数中,将一个虚拟项加到$scope变量中,该变量在md-autocomplete中绑定.但是我在这次尝试中失败了.因为在这里我也得到了与快照中相同的输出.
function Ctrlm($scope) { $scope.messageToUser = "You are done!"; setTimeout(function () { $scope.$apply(function () { $scope.dummyCntry = [ { sno: 0,country: "" },]; $scope.Person.push($scope.dummyCntry); var index = $scope.Person.indexOf($scope.dummyCntry); $scope.Person.splice(index,1); }); },10); }
案例4:我在$scope中使用了与“Case 3”相同的方法.$watchCollection.在这里我也遇到了挫折.
$scope.$watchCollection('Person',function (newData,oldDaata) { $scope.dummyCntry = [ { sno: 0,]; newData.push($scope.dummyCntry); var index = newData.indexOf($scope.dummyCntry); newData.splice(index,1); });
案例5:我使用jquery ajax调用而不是$http服务.在那里,我使用$scope.apply()手动更新UI.我再一次尝试失败了,这里也得到了相同的输出.
$scope.searchTextChange = function () { if (($scope.searchText != undefined) && ($scope.searchText != null)) { $.ajax({ type: 'GET',url: "https://www.bbminfo.com/sample.PHP?token=" + $scope.searchText,success: function (response) { $scope.$apply(function () { $scope.Person = response.records; }); },error: function (data) { $scope.$apply(function () { $scope.Person = []; }); },async: true }); } else { $scope.Person = []; } }
In all the attempts I can’t able to fix the issue.
@georgeawg https://stackoverflow.com/users/5535245/georgeawg建议我发布一个新问题,他说,“写一个新问题,描述你实际上想要实现的目标,包括所需的行为,到目前为止你为解决问题所做的工作总结,以及你解决它的困难的描述.“
我之前发布的参考问题
My Requirement: I need an updated Suggestion List using remote data
sources in Angular Materialmd-autocomplete
– Ajax$http
service.
请在这方面帮助我.
For Testing Purpose Use the following Source Code
对远程数据源使用以下URL:https://bbminfo.com/sample.php?token=ind
远程数据源URL包含国家/地区名称列表.
Directly Test the Code by click the below Run Code Snippet button.
使用AngularJS完整HTML源代码:
<!DOCTYPE html> <html> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css"> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script> <!-- Angular Material Library --> <script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script> <body> <div ng-app="myApp" ng-controller="myCtrl"> <p>Country to Select:</p> <md-content> <md-autocomplete ng-disabled="isDisabled" md-no-cache="noCache" md-selected-item="selectedItem" md-search-text-change="searchTextChange()" md-search-text="searchText" md-selected-item-change="selectedItemChange(item)" md-items="item in Person" md-item-text="item.country" md-min-length="0" placeholder="Which is your favorite Country?"> <md-item-template> <span md-highlight-text="searchText" md-highlight-flags="^i">{{item.country}}</span> </md-item-template> <md-not-found> No Person matching "{{searchText}}" were found. </md-not-found> </md-autocomplete> </md-content> <br/> </div> <script> var app = angular.module('myApp',$q) { $scope.searchText = ""; $scope.Person = []; $scope.selectedItem = []; $scope.isDisabled = false; $scope.noCache = false; $scope.selectedItemChange = function (item) { alert("Item Changed"); } $scope.searchTextChange = function () { $http({ method: "post",params: { token: $scope.searchText } }) .success(function (response) { $scope.Person = response.records; }); } }); </script> </body> </html>
我得到了Exact解决方案,我需要什么.
源代码是
<!DOCTYPE html> <html> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css"> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script> <!-- Angular Material Library --> <script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.4/angular-material.min.js"></script> <body> <div ng-app="myApp" ng-controller="myCtrl"> <p>Country to Select:</p> <md-content> <md-autocomplete ng-disabled="isDisabled" md-no-cache="noCache" md-selected-item="selectedItem" md-search-text="searchText" md-items="item in searchTextChange(searchText)" md-item-text="item.country" md-min-length="0" placeholder="Which is your favorite Country?"> <md-item-template> <span md-highlight-text="searchText" md-highlight-flags="^i">{{item.country}}</span> </md-item-template> <md-not-found> No Person matching "{{searchText}}" were found. </md-not-found> </md-autocomplete> </md-content> <br/> </div> <script> var app = angular.module('myApp',$q,GetCountryService) { $scope.searchText = ""; $scope.Person = []; $scope.selectedItem = []; $scope.isDisabled = false; $scope.noCache = false; $scope.selectedItemChange = function (item) { //alert("Item Changed"); } $scope.searchTextChange = function (str) { return GetCountryService.getCountry(str); } }); app.factory('GetCountryService',function ($http,$q) { return { getCountry: function(str) { // the $http API is based on the deferred/promise APIs exposed by the $q service // so it returns a promise for us by default var url = "https://www.bbminfo.com/sample.PHP?token="+str; return $http.get(url) .then(function(response) { if (typeof response.data.records === 'object') { return response.data.records; } else { // invalid response return $q.reject(response.data.records); } },function(response) { // something went wrong return $q.reject(response.data.records); }); } }; }); </script> </body> </html>
我在以下博客中简要介绍了md-autocomplete – http://www.increvcorp.com/usage-of-md-autocomplete-in-angular-material/