我正在使用带有asp.net mvc的angularjs。在我的页面上,我有5个下拉列表,所有下拉列表都填充了来自不同数据库表的值。为了检索所有下拉列表的数据,我正在制作5个不同的$ http.get请求,这使得我的页面加载时间变慢。我知道这是设置错误,但不知道如何正确地做到这一点。这是我的角度代码,它调用mvc动作,返回下拉列表的值。将结果传递到$ scope,下拉列表显示:
var CustomSearchController = function ($scope, $http) {
$http.get('/Account/GetLists')
.success(function (result) {
$scope.listDetails = result;
})
};
$http.get('/Account/GetGenders')
.success(function (result) {
$scope.genderDetails = result;
})
};
$http.get('/Account/GetEthnicities')
.success(function (result) {
$scope.ethnicityDetails = result;
})
};
$http.get('/Account/GetRegions')
.success(function (result) {
$scope.regionDetails = result;
})
};
$http.get('/Account/GetAcademics')
.success(function (result) {
$scope.academicDetails = result;
})
};
正确的方法是什么?
答案 0 :(得分:3)
您应该使用$httpProvider.useApplyAsync
并传递true
。
配置$ http服务,通过$ rootScope。$ applyAsync组合大约同时收到的多个http响应的处理。对于同时发出许多HTTP请求的大型应用程序(在应用程序引导期间很常见),这可以显着提高性能。
这意味着如果为true,则在加载请求时,他们将在下一个tick上安排延迟“apply”,在大约10ms的窗口中为后续请求提供时间来加载和共享相同的摘要周期。
简而言之,您可以避免不必要的摘要周期,可以造成一些差异。
只需将$httpProvider
传递到您的运行功能并修改提供程序,如下所示:
angular.module('MyApp', [])
.run(function($httpProvider){
$httpProvider.useApplyAsync(true);
});
答案 1 :(得分:0)
您可以将$q
服务用于以下情况:
var CustomSearchController = function ($scope, $q, $log, $http) {
var listPromise = $http.get('/Account/GetLists');
var genderPromise = $http.get('/Account/GetGenders');
var ethnicCitiesPromise = $http.get('/Account/GetEthnicities')
var regionsPromise = $http.get('/Account/GetRegions')
var academicPromise = $http.get('/Account/GetAcademics');
$q.all([genderPromise, ethnicCitiesPromise, regionsPromise, academicPromise])
.then(function (responses) {
// Here you have all the resolved datas
// responses[0]
// responses[1]
// responses[2]
// responses[3]
}).catch(function (error) {
$log.error(error);
throw error;
})
}
但是我更喜欢调用每个下拉列表的ng-change
函数来以级联方式检索数据。
答案 2 :(得分:0)
试试这样: 你的控制器(主视图):
ViewBag.regionDetailsJson = new JavaScriptSerializer().Serialize(regionDetails );
在您看来:
var regionDetailsJson = $.parseJSON('@Html.JsonRaw((string)ViewBag.regionDetailsJson )');
而不是你的角度控制器:
$scope.regionDetailsJson = regionDetailsJson;
答案 3 :(得分:0)
使用HFA建议的promises是一种更加Angular的方法,但它仍会导致对服务器的5次调用;因此,无法真正帮助提高页面加载性能 - 即在获取数据之前,您仍将等待5个承诺解决。
您可以尝试的一件事是在加载MVC帐户操作所服务的页面时制定此列表,并将这些列表保存到页面模型中。然后,您可以在脚本块中访问此客户端,将它们分配给(全局)变量,然后您可以在Angular中访问该变量。
我没有对此进行测试,但过去有这种方法。作为指导,您需要遵循的步骤是:
在您的AccountController中
public ActionResulst Index() {
var model = new AccountModel {
Lists = GetLists(),
Ethnicities = GetLists()
}
return View(model);
}
然后在你的Razor页面上
@model AccountModel
<script>
window.lists= "@(Model.Lists)";
window.ethnicities = "@(Model.Ethnicities )";
</script>
然后在你的Angular中
var CustomSearchController = function ($window) {
var lists = $window.lists;
var ethnicities = $window.ethnicities;
}
您可能需要使用JSON.Parse
将结果转换为JSON答案 4 :(得分:0)
你的方法没有错。您关注的是分离关注和单一责任。
如果您从ASP.Net MVC View中获取模型或 ViewModel 的日期,则无法轻松地对Angular Services进行单元测试。
另一种方法是使用 resolve 。它基本上在路由执行之前加载数据。 仅供参考 :尽管您可以显示页面加载图标,但它不会改善整体加载时间。
Demo for Angular 1.5 Route Resolve at Plunker
(function () {
angular
.module("app", ['ngRoute'])
.config(function($routeProvider){
$routeProvider
.when("/home", {
template: `<main
promise-followers="$resolve.promiseFollowers"></main>`,
resolve: {promiseFollowers: function ($http) {
return $http.get("https://api.github.com/users/octocat/followers")
.then(function(result) {
return result.data;
}, function(result) {
console.log(result);
});
}
},
})
.otherwise({ redirectTo: "/home" } );
})
.component("main", {
template: `<h3>Demo Angular 1.5 Resolver</h3>
<p>Promise Data from Resolve :
<select ng-model="$ctrl.selected"
ng-options="option.id as option.login for option in $ctrl.promiseFollowers"></select>
</p>
<h4>Regular Selector Selected: {{$ctrl.selected}}</h4>`,
bindings: {
promiseFollowers: '='
},
controller: function(){
}
});
})();
&#13;
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script>document.write('<base href="' + document.location + '" />');</script>
<script src="https://code.angularjs.org/1.5.7/angular.js"></script>
<script src="https://code.angularjs.org/1.5.7/angular-route.js"></script>
<script src="app.js"></script>
</head>
<body>
<ng-view></ng-view>
</body>
</html>
&#13;