$http 问题 - 在 md-autocomplete Angular Material 中解决承诺之前无法返回值
$http issue - Values can't be returned before a promise is resolved in md-autocomplete Angular Material
我在我的项目中使用 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
中提到的方法
源代码:
场景一:
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;
}
场景二:
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",
url: "https://www.bbminfo.com/sample.php",
params: {
token: $scope.searchText
}
})
.success(function (response) {
$scope.Person = response.records;
});
}
});
</script>
</body>
</html>
在场景 1 中,我使用函数来获取筛选列表 md-items="item in querySearch(searchText)"
。但是在场景2中,我使用了一个$scope
变量md-items="item in Person"
请参考快照
快照 1:
我在这里搜索 indian 但它显示 india 的结果。我在 Firefox 浏览器 Firebug 中调试了这个问题,看到上面的 Snapshot 1 它显示,请求已发送搜索词 indian 通过 POST 方法,我成功地得到了一个匹配项作为 JSON 对象的响应,显示在 SnapShot 1 的底部
The issue I find out in this case, the Values can't be returned before
a promise is resolved
我尝试的步骤:
案例1:我在UImd-items="item in Person | filter: searchText"
中使用了AngularJSfilter
,它给出了之前的过滤列表获取的远程数据不是当前获取的远程数据。在退格文本框中的字符时,它显示不正确的建议列表。
案例 2:我试图通过在 $http
服务中调用 $scope.$apply()
来更新 UI 中的更改,但它失败了。因为 $http
服务默认调用 $scope.$apply()
,显示它会抛出错误 Error: [$rootScope:inprog]...。最后在这次尝试中我失败了。
案例 3:我创建了一个函数,在该函数中我手动调用了 $scope.$apply()
,在该函数中我手动将一个虚拟项推送并弹出到在 md-autocomplete
中绑定的 $scope
变量。但是我这次尝试失败了。因为这里我也得到了与快照中相同的输出。
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.$watchCollection 中采用了与 "Case 3" 相同的方法。在这里我也遇到了挫折。
$scope.$watchCollection('Person', function (newData, oldDaata) {
$scope.dummyCntry = [
{
sno: 0,
country: ""
},
];
newData.push($scope.dummyCntry);
var index = newData.indexOf($scope.dummyCntry);
newData.splice(index, 1);
});
案例 5:我使用 jquery ajax 调用 [=139= 而不是 $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://whosebug.com/users/5535245/georgeawg 建议我 post 一个新问题,他说,“写一个新问题来描述你实际想要完成的事情,包括你想要的行为,到目前为止你为解决问题所做的工作的总结,以及你在解决问题时遇到的困难的描述。"
我在之前 post 编辑的参考问题
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', ['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",
url: "https://www.bbminfo.com/sample.php",
params: {
token: $scope.searchText
}
})
.success(function (response) {
$scope.Person = response.records;
});
}
});
</script>
</body>
</html>
@KevinB https://whosebug.com/users/400654/kevin-b - 给出了如何实施的想法。我真的很感谢他...再次感谢凯文...
我得到了我需要的确切解决方案。
源代码是
<!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', ['ngMaterial']);
app.controller('myCtrl', function ($scope, $http, $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/
为什么不直接将 return countryList 放入成功函数中。
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;
})
.error(function (response) {
countryList = [];
return countryList;
});
}
由于 .success 和 .error 方法的弃用而编辑:
function LoadAutocomplete(id) {
var countryList = [];
$http({
method: "post",
url: "https://www.bbminfo.com/sample.php",
params: {
token: id
}
})
.then(function (response) {
countryList = response.data.records;
return countryList;
},function () {
countryList = [];
return countryList;
});
}
我也为此苦苦挣扎了一会儿。基本上,您实际上应该返回 returns 内容的承诺。
这是我的"search"函数
$scope.searchData = function (searchTxt) {
return $http.get('/TestSearch', { params: { searchStr: searchTxt } })
.then(function(response) {
return response.data;
});
};
另外我不确定你 angular 是哪个版本 运行 但我认为 .success 已被弃用。
这也是我的 md-autocomplete
<md-autocomplete placeholder="Text goes here"
md-selected-item="vm.autocomp"
md-search-text="searchText"
md-items="item in searchData(searchText)"
md-item-text="item">
<span md-highlight-text="searchText">{{item}}</span>
</md-autocomplete>
编辑1:
抱歉,原始 JS 在 TypeScript 中。现在解决这个问题
标记的答案是正确的。
- .then() - 承诺的全部力量 API 但稍微冗长
- .success() - 不是 return 承诺,但提供了稍微更方便的语法
我在我的项目中使用 Angular Material md-autocomplete
。因为我使用 $http
服务通过 ajax 调用从服务主机获得建议列表。
Issue: $http issue - Values can't be returned before a promise is resolved in
md-autocomplete
Angular MaterialMy 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
中提到的方法源代码:
场景一:
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;
}
场景二:
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",
url: "https://www.bbminfo.com/sample.php",
params: {
token: $scope.searchText
}
})
.success(function (response) {
$scope.Person = response.records;
});
}
});
</script>
</body>
</html>
在场景 1 中,我使用函数来获取筛选列表 md-items="item in querySearch(searchText)"
。但是在场景2中,我使用了一个$scope
变量md-items="item in Person"
请参考快照
快照 1:
我在这里搜索 indian 但它显示 india 的结果。我在 Firefox 浏览器 Firebug 中调试了这个问题,看到上面的 Snapshot 1 它显示,请求已发送搜索词 indian 通过 POST 方法,我成功地得到了一个匹配项作为 JSON 对象的响应,显示在 SnapShot 1 的底部
The issue I find out in this case, the Values can't be returned before a promise is resolved
我尝试的步骤:
案例1:我在UImd-items="item in Person | filter: searchText"
中使用了AngularJSfilter
,它给出了之前的过滤列表获取的远程数据不是当前获取的远程数据。在退格文本框中的字符时,它显示不正确的建议列表。
案例 2:我试图通过在 $http
服务中调用 $scope.$apply()
来更新 UI 中的更改,但它失败了。因为 $http
服务默认调用 $scope.$apply()
,显示它会抛出错误 Error: [$rootScope:inprog]...。最后在这次尝试中我失败了。
案例 3:我创建了一个函数,在该函数中我手动调用了 $scope.$apply()
,在该函数中我手动将一个虚拟项推送并弹出到在 md-autocomplete
中绑定的 $scope
变量。但是我这次尝试失败了。因为这里我也得到了与快照中相同的输出。
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.$watchCollection 中采用了与 "Case 3" 相同的方法。在这里我也遇到了挫折。
$scope.$watchCollection('Person', function (newData, oldDaata) {
$scope.dummyCntry = [
{
sno: 0,
country: ""
},
];
newData.push($scope.dummyCntry);
var index = newData.indexOf($scope.dummyCntry);
newData.splice(index, 1);
});
案例 5:我使用 jquery ajax 调用 [=139= 而不是 $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://whosebug.com/users/5535245/georgeawg 建议我 post 一个新问题,他说,“写一个新问题来描述你实际想要完成的事情,包括你想要的行为,到目前为止你为解决问题所做的工作的总结,以及你在解决问题时遇到的困难的描述。"
我在之前 post 编辑的参考问题
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', ['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",
url: "https://www.bbminfo.com/sample.php",
params: {
token: $scope.searchText
}
})
.success(function (response) {
$scope.Person = response.records;
});
}
});
</script>
</body>
</html>
@KevinB https://whosebug.com/users/400654/kevin-b - 给出了如何实施的想法。我真的很感谢他...再次感谢凯文...
我得到了我需要的确切解决方案。
源代码是
<!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', ['ngMaterial']);
app.controller('myCtrl', function ($scope, $http, $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/
为什么不直接将 return countryList 放入成功函数中。
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;
})
.error(function (response) {
countryList = [];
return countryList;
});
}
由于 .success 和 .error 方法的弃用而编辑:
function LoadAutocomplete(id) {
var countryList = [];
$http({
method: "post",
url: "https://www.bbminfo.com/sample.php",
params: {
token: id
}
})
.then(function (response) {
countryList = response.data.records;
return countryList;
},function () {
countryList = [];
return countryList;
});
}
我也为此苦苦挣扎了一会儿。基本上,您实际上应该返回 returns 内容的承诺。
这是我的"search"函数
$scope.searchData = function (searchTxt) {
return $http.get('/TestSearch', { params: { searchStr: searchTxt } })
.then(function(response) {
return response.data;
});
};
另外我不确定你 angular 是哪个版本 运行 但我认为 .success 已被弃用。
这也是我的 md-autocomplete
<md-autocomplete placeholder="Text goes here"
md-selected-item="vm.autocomp"
md-search-text="searchText"
md-items="item in searchData(searchText)"
md-item-text="item">
<span md-highlight-text="searchText">{{item}}</span>
</md-autocomplete>
编辑1: 抱歉,原始 JS 在 TypeScript 中。现在解决这个问题
标记的答案是正确的。
- .then() - 承诺的全部力量 API 但稍微冗长
- .success() - 不是 return 承诺,但提供了稍微更方便的语法