AngularJs返回多个动态下拉列表的数据

时间:2016-09-06 19:38:22

标签: angularjs asp.net-mvc

我正在使用带有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;
    })        
 };

正确的方法是什么?

5 个答案:

答案 0 :(得分:3)

您应该使用$httpProvider.useApplyAsync并传递true

来自documentation

  

配置$ 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

&#13;
&#13;
(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;
&#13;
&#13;