2015-09-17 35 views
1

我一直在試圖將一堆代碼放入服務中,而不是讓它坐在控制器中,因爲我的應用程序中的其他控制器將需要某些相同的功能。我有以下的控制器代碼:服務中的角度函數不被視爲函數

JBenchApp.controller('CaseListCtrl', ['$scope', '$http', 'HoldState', 
    function ($scope, $http, HoldState) { 

     //---------------------------------------------------------- 
     // Load the Calendar Data whent he department changes 
     //---------------------------------------------------------- 

     $scope.getCalendarOnDeptChange = function() { 
      // Get the dropdown into e 
      var e = document.getElementById("deptSelect"); 

      // Set $scope.department to the text of the selected dropdown item --- MUST FIND BETTER ANGULAR METHOD 
      $scope.department = e.options[e.selectedIndex].text; 
      console.log($scope.department); 
      $scope.getCalendar(); 
     }; 


     //---------------------------------------------------------- 
     // Load the calendar data 
     //---------------------------------------------------------- 

     $scope.getCalendar = function() { 
      // Retrieve calendar data 
      HoldState.getCalendar($scope.lastDepartment, $scope.date, $scope.lastLawType, $scope.lastLocationID).then(function (data) { 
       $scope.cases = data; 
       $scope.$apply(); 
      }); 

      HoldState.setDepartment($scope.department); 
     }; 

     //---------------------------------------------------------- 
     // Load the user's default settings 
     //---------------------------------------------------------- 

     $scope.loadDefaults = function() { 
      HoldState.getUserDefaults($scope.UserID).then(function (data) { 
       $scope.UserDefaults = data; 
      }); 

      $scope.defaultDepartment = $scope.UserDefaults.CourtRoom; 
      $scope.defaultLawType = $scope.UserDefaults.LitigationCode; 
      $scope.defaultLocationID = $scope.UserDefaults.LocID; 
     }; 

     $scope.loadPaths = function() { 
      HoldState.getTypeOfLaw().then(function (data) { 
       $scope.lastLawType = data; 
      }); 

      HoldState.getCourthouse().then(function (data) { 
       $scope.lastLocationID = data; 
      }); 

      HoldState.getDepartment().then(function (data) { 
       $scope.lastDepartment = data; 
      }); 
     }; 


     $scope.doAuthentication = function() { 
      $scope.UserID = 'dpeng'; 
     }; 

     $scope.saveSequence = function() { 

     }; 

     //---------------------------------------------------------- 
     // Initial processing 
     //  Located here so that all functions are defined before 
     //  being called. 
     // 1. Authenticate the user 
     // 2. Get the default values 
     // 3. Load the paths 
     // 4. Get the list of departments 
     // 5. Show the calendar. 
     //---------------------------------------------------------- 
     $scope.doAuthentication(); 
     $scope.loadDefaults(); 
     $scope.loadPaths(); 

     HoldState.getDepartmentList($scope.lastLawType, $scope.lastLocationID).then(function (data) { 
      $scope.departments = data; 
     }); 

     $scope.getCalendar(); 

    }]); 

我也有以下服務代碼:

當我打電話$scope.loadDefaults();我得到一個錯誤,指出:

TypeError: HoldState.getUserDefaults(...).then is not a function 
    at m.$scope.loadDefaults (http://localhost:54365/js/controllers.js:78:52) 
    at new <anonymous> (http://localhost:54365/js/controllers.js:121:14) 
    at Object.e [as invoke] (http://localhost:54365/js/angular.min.js:36:315) 
    at x.instance (http://localhost:54365/js/angular.min.js:76:79) 
    at http://localhost:54365/js/angular.min.js:59:85 
    at q (http://localhost:54365/js/angular.min.js:7:428) 
    at M (http://localhost:54365/js/angular.min.js:59:69) 
    at g (http://localhost:54365/js/angular.min.js:51:409) 
    at http://localhost:54365/js/angular.min.js:51:17 
    at chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:2071:22 <div ng-view="" class="view-frame ng-scope">(anonymous function) @ angular.min.js:102 
angular.min.js:102 TypeError: Cannot read property 'getStatus' of undefined 
    at controllers.js:311 
    at angular.min.js:112 
    at m.$eval (angular.min.js:126) 
    at m.$digest (angular.min.js:123) 
    at m.scopePrototype.$digest (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:1955) 
    at m.$apply (angular.min.js:127) 
    at m.scopePrototype.$apply (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:2018) 
    at l (angular.min.js:81) 
    at P (angular.min.js:85) 
    at XMLHttpRequest.H.onload (angular.min.js:86)(anonymous function) @ angular.min.js:102 

我有什麼做錯了?我只是試圖通過我的Angular服務乾淨地從Web服務中獲取數據。

+0

是對JBenchApp模塊注入的StateService模塊的依賴? –

+0

是: 'var JBenchApp = angular.module('JBenchApp',[ 'ngRoute', 'StateService' ]);' –

+0

你正在對待他們返回promise的方法(.then()不是函數) –

回答

1

getUserDefaults是真正需要承諾的唯一方法,因爲您正在對api進行異步調用。因此,將$ q注入到您的服務中,然後讓該方法返回一個承諾。

this.getUserDefaults = function (UserID) { 
    var userDefaults = [], deferred = $q.defer(); 
    $http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID) 
     .then(function (response) { 

      var status = this.getStatus(); 

      // If the status is 0 then we have not yet navigated anywhere so we will need to set the path values to be 
      // the same as the default. We do nothing if status is not 0 because it means we already have path values set 
      if (status == 0) { 
       this.setTypeOfLaw(response.LitigationCode); 
       this.setCourthouse(response.LocID); 
       this.setDepartment(response.CourtRoom); 
      } 
      d.resolve(response); 
     }, function (response) { 
      console.log(response.status + " -- " + response.data + " -- " + response.statusText); 
     }); 


    return deferred.promise; 
}; 

你也應該使用getters作爲getters,而不是試圖把它們當作promise。 即

$scope.loadPaths = function() { 
     $scope.lastLawType = HoldState.getTypeOfLaw(); 

     $scope.lastLocationID = HoldState.getCourthouse(); 

     $scope.lastDepartment = HoldState.getDepartment(); 
    }; 
+0

與此相關的另一個問題是,如何在另一個函數內調用服務中的一個函數?在getUserDefaults裏面我有: 'var status = this.getStatus()' 這是行不通的。我已將其更改爲: 'var status = getStatus()' 那一個抱怨說getStatus是未定義的。 那麼如何從getUserDefaults函數中調用服務的getStatus函數呢? –

+0

您傳遞給then方法的回調函數不會保留父變量作用域,因此在您的代碼中,this是未定義的。您需要在共享父作用域中設置一個變量,作爲您想要在服務中引用的方法的引用。我更喜歡不同的結構來完全編寫服務,就像我在這個codepen中演示的那樣:http://codepen.io/anon/pen/vNGvLq?editors=001 –

0

再看一下錯誤:

HoldState.getUserDefaults(...).then is not a function 
           ^^^^ 

HoldState.getUserDefaults()沒有返回一個承諾,這就是問題所在。

爲了能夠使用該服務就像你在那一刻,調整的方法一點:

this.getUserDefaults = function (UserID) { 
    return $http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID) 
     .then(function (response) { 
      var status = this.getStatus(); 

      // If the status is 0 then we have not yet navigated anywhere so we will need to set the path values to be 
      // the same as the default. We do nothing if status is not 0 because it means we already have path values set 
      if (status == 0) { 
       this.setTypeOfLaw(response.LitigationCode); 
       this.setCourthouse(response.LocID); 
       this.setDepartment(response.CourtRoom); 
      }  
     }, function (response) { 
      console.log(response.status + " -- " + response.data + " -- " + response.statusText); 
     }); 

}; 

由於承諾是可鏈接的,你基本上是回你從$http.get()得到的承諾,這將是用response解決。這應該使它工作。

+0

still將不起作用,因爲引用被破壞到實際返回的內容 – charlietfl

0

這應該可以解決這個問題

$scope.loadDefaults = function() { 
     HoldState.getUserDefaults($scope.UserID).then(function (data) { 
      $scope.UserDefaults = data; 
     }, function(errData) { 
      //$scope.UserDefaults isn't going to get filled, so do some error handling here. 
     }); 

     $scope.defaultDepartment = $scope.UserDefaults.CourtRoom; 
     $scope.defaultLawType = $scope.UserDefaults.LitigationCode; 
     $scope.defaultLocationID = $scope.UserDefaults.LocID; 
    }; 

而且

//Begin default settings 
this.getUserDefaults = function (UserID) { 
    //Here we return the promise 
    return $http.get('http://10.34.34.46/BenchViewServices/api/UserPreference/Default/' + UserID) 
     .then(function (response) { 
      userDefaults = response; 
      var status = this.getStatus(); 

      // If the status is 0 then we have not yet navigated anywhere so we will need to set the path values to be 
      // the same as the default. We do nothing if status is not 0 because it means we already have path values set 
      if (status == 0) { 
       this.setTypeOfLaw(response.LitigationCode); 
       this.setCourthouse(response.LocID); 
       this.setDepartment(response.CourtRoom); 
      } 
      //Here we fill the data variable 
      return response; 

     }, function (response) { 
      console.log(response.status + " -- " + response.data + " -- " + response.statusText); 
     }); 

};