angularjs – $http issue – 在md-autocomplete Angular Material中解析promise之前,不能返回值

前端之家收集整理的这篇文章主要介绍了angularjs – $http issue – 在md-autocomplete Angular Material中解析promise之前,不能返回值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在我的项目中使用Angular Material md-autocomplete.在那里我通过使用$http服务的ajax调用从服务主机获取建议列表.

Issue: $http issue – Values can’t be returned before a promise is
resolved in md-autocomplete Angular Material

My Requirement: I need an updated Suggestion List using remote data
sources in md-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建议我发布一个新问题,他说,“写一个新问题,描述你实际上想要实现的目标,包括所需的行为,到目前为止你为解决问题所做的工作总结,以及你解决它的困难的描述.“

我之前发布的参考问题

邮报1:http://www.stackoverflow.com/questions/35624977/md-items-is-not-updating-the-suggesion-list-properly-in-md-autocomplete-angular

邮报2:http://www.stackoverflow.com/questions/35646077/manually-call-scope-apply-raise-error-on-ajax-call-error-rootscopeinprog

My Requirement: I need an updated Suggestion List using remote data
sources in Angular Material md-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>
@KevinB https://stackoverflow.com/users/400654/kevin-b – 给出了如何实施的想法.我真的很感谢他……再一次感谢Kevin …

我得到了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/

原文链接:https://www.f2er.com/angularjs/143710.html

猜你在找的Angularjs相关文章