2016-09-06 2 views
0

Я использую angularjs с asp.net mvc. На моей странице у меня есть 5 выпадающих списков, заполненных значениями из разных таблиц базы данных. Чтобы получить данные для всех выпадающих списков, я делаю 5 разных запросов $ http.get, что замедляет загрузку страницы на сканирование. Я знаю, что это неправильно, но не уверен, как это сделать. Вот мой угловой код, который делает вызов на Mvc действия, возвращает значения для выпадающего списка & передает результаты в $ рамки для выпадающего списка для отображения:AngularJs возвращает данные для нескольких динамических выпадающих списков

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; 
    })   
}; 

Что правильный путь об этом ?

+2

Я не могу сказать, эта установка не так! , Вы можете улучшить время загрузки, кэшируя данные на своем сервере для этих конечных точек. Другой вариант - иметь единственную конечную точку, которая возвращает данные для всех 5 выпадающих списков в 5 разных свойствах возвращаемого объекта. – Shyju

ответ

3

Вы должны используйте $httpProvider.useApplyAsync и перейдите в true.

От documentation:

Настройка службы $ HTTP сочетать обработку нескольких ответов HTTP, полученные примерно в то же время с помощью $ rootScope $ applyAsync.. Это может привести к значительному повышению производительности для крупных приложений, которые одновременно выполняют множество HTTP-запросов (обычно во время загрузки приложения).

Это означает, что если это правда, когда запросы загружается, они будут планировать отложенный «применить» на следующем такте, давая время для последующих запросов в примерно ~ 10мс окна для загрузки и один и те же переваривание цикла.

Короче говоря, вы можете избежать ненужных циклов дайджестов, которые может сделать чертову разницу.

Просто передайте $httpProvider в вашу функцию запуска и изменить поставщика, как так:

angular.module('MyApp', []) 

.run(function($httpProvider){ 

    $httpProvider.useApplyAsync(true); 

}); 
+0

Я не знал об этом, спасибо. – Kildareflare

+0

Нет проблем, нет ничего плохого в том, чтобы делать отдельные запросы. У меня есть приложение с примерно 40 подобными запросами и работает отлично :) – cnorthfield

+0

@ Kildareflare ответили на этот вопрос, ответьте на ваш вопрос? – cnorthfield

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 каждого выпадающего меню для извлечения данных в стиле каскада.

+0

Как 'q' помогает в этой утилите? q полезно избегать древовидного дерева. – Shyju

+0

@ Шыю, какого черта вы имеете в виду? у нас есть ад, используя обещания! – Rachmaninoff

0

Попробуйте так: ваш контроллер (основной вид):

ViewBag.regionDetailsJson = new JavaScriptSerializer().Serialize(regionDetails); 

На ваш взгляд:

var regionDetailsJson = $.parseJSON('@Html.JsonRaw((string)ViewBag.regionDetailsJson)'); 

И чем в вашей угловой контроллер:

$scope.regionDetailsJson = regionDetailsJson; 
0

Использование обещаний как это было предложено HFA является более Угловая подход, но он все равно будет приводить к 5 обращений к серверу; поэтому на самом деле не поможет улучшить производительность загрузки страницы - т. е. вы все равно будете ждать 5 обещаний, которые разрешат, прежде чем вы получите свои данные.

Одна вещь, которую вы можете попробовать, - это сформулировать эти списки, когда страница, обслуживаемая действием вашей учетной записи MVC, будет загружена и сохранит их на странице модели. Затем вы можете получить доступ к этой стороне клиента в блоке сценария, назначив им (глобальную) переменную, доступ к которой вы можете получить в режиме Угловая.

Я не тестировал это, но у вас был такой подход в прошлом. В качестве руководства шаги, которые необходимо будет следовать являются:

В вашем AccountController

public ActionResulst Index() { 
    var model = new AccountModel { 
    Lists = GetLists(), 
    Ethnicities = GetLists() 
    } 
    return View(model); 
} 

Тогда на бритву Страница

@model AccountModel 
    <script> 
     window.lists= "@(Model.Lists)"; 
     window.ethnicities = "@(Model.Ethnicities)"; 
    </script> 

Затем в угловых

var CustomSearchController = function ($window) { 

var lists = $window.lists; 
var ethnicities = $window.ethnicities; 
} 

Вы может потребоваться преобразование результатов в JSON с использованием JSON.Parse

0

Нет ничего плохого в вашем подходе. Вы следите за разделом озабоченности и единой ответственностью.

Если вы получите дату от модели или ViewModel из ASP.Net MVC View, вы не можете Unit Test Угловая Services легко.

Другой подход заключается в использовании resolve. Он загружает данные сначала до начала маршрута. FYI: Это не улучшит общее время загрузки, хотя вы можете отобразить значок загрузки страницы.

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(){ 
 
      
 
     } 
 
     }); 
 
     
 
})();
<!DOCTYPE html> 
 
<html ng-app="app"> 
 

 
    <head> 
 
    <meta charset="utf-8" /> 
 
    <title>AngularJS Plunker</title> 
 
    <link data-require="[email protected]" 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>

Смежные вопросы