Angularjs级联下拉列表

时间:2016-06-08 13:54:44

标签: angularjs asp.net-mvc

我需要使用角度服务来创建级联下拉列表。我为测试目的而创建的注释代码,它工作正常。我需要创建两个服务来从MVC控制器调用两个方法:GetCompanies()和GetDocTypes() 我的问题是:我的第一个服务是否正确,如何从控制器调用服务? 谢谢。

/// <reference path="angular.js" />
//var myApp = angular
//    .module("myApp", [])
//    .controller("companyController", function ($scope, $http) {

//    $http.post('CurrentSettings/GetCompanies')
//        .then(function (response) {
//            var response = $.parseJSON(response.data);
//            $scope.currentSettings = response;
//        });
//    });

var myApp = angular.module("myApp", []);

myApp.service('getCompanies', function () {
$http.post('CurrentSettings/GetCompanies')
.then(function (response) {
    var response = $.parseJSON(response.data);
    $scope.currentSettings = response;
    });
});

myApp.controller("companyController", function ($scope, getCompanies,   $http) {
});

1 个答案:

答案 0 :(得分:0)

您服务的问题有两个:

首先,无法调用该服务。你注射它很好,但现在呢?将您的服务视为API;只是在某个地方引用它并不好,你需要能够使用它。我会改为:

var myApp = angular.module("myApp", []);    
myApp.service('getCompanies', ["$http", function($http) {
  this.currentSettings = "Hello";
  $http.post('CurrentSettings/GetCompanies')
    .then(function(response) {
      var response = $.parseJSON(response.data);
      this.currentSettings = response;
    });    
}]);

myApp.controller("companyController", ["$scope", "getCompanies", 
function($scope, getCompanies) {
  $scope.currentSettings = getCompanies.currentSettings;
}]);

请注意以下几点:

  1. 您需要明确地将$ http注入您的服务。
  2. 我指定我作为包含该函数的数组的一部分注入的服务的名称。这实际上允许您为任何您想要的参数命名,并被认为是最佳实践。
  3. 该服务不直接使用$ scope。相反,它使该字段可用于该服务的客户端。然后,该客户端(在这种情况下为控制器)可以随意使用该值,包括将其分配给$ scope字段。
  4. 控制器从服务中读取此字段。它也可以调用您指定的任何函数 - 使服务成为API,如前所述。
  5. 第二个问题是时间问题。请注意,我使用超级原始值“Hello”来初始化服务字段。

    从服务收到的值取决于控制器在调用MVC控制器后是否读取值。

    要解决此问题,该服务可能会公开第二个字段以指示公司列表已完全加载,但这确实会改变问题而不是修复它。

    您需要的是一个返回承诺的函数。如果该值已加载,则promise立即解析。如果没有,它将返回一个$ http调用完成后将返回的promise。

    以下是修改后的代码:

    var myApp = angular.module("myApp", []);
    myApp.service('companiesService', ['$http', '$q', function($http, $q) {
      var currentSettings = null;
    
      this.getList = function() {
        var def = $q.defer()
        if (currentSettings) {
          def.resolve(currentSettings);
        } else {
          $http.get('CurrentSettings/GetCompanies')
            .then(function(response) {
              var response = response.data;
              currentSettings = response;
              def.resolve(currentSettings);
            });
        }
        return def.promise;
      }
    }]);
    
    myApp.controller('companyController', ['$scope', 'companiesService',
      function($scope, companiesService) {
        $scope.currentSettings = '';
        companiesService.getList().then(function(value) {
          $scope.currentSettings = value;
        });
      }
    ]);
    

    它变得有点复杂,因为你必须使用promises,但这些是需要注意的事项:

    1. 我更改了服务的名称,使其更通用。它现在可以提供许多与公司相关的功能。
    2. currentSettings不再添加到服务上,而是成为普通(私有)变量。调用代码只能通过调用getList函数来读取它。
    3. getList返回一个promise。如果已分配currentSettings,则立即解析promise。如果不是,则只有在从Web服务收到值后才会解析。
    4. 控制器调用getList并将值分配给then函数中的$ scope字段。