2013-07-09 97 views
1

我是Angular的新手。我有一個簡單的網頁,但控制器的代碼不起作用。看來我沒有正確地在控制器中調用或注入服務「ListLogsFactory」。請幫忙。謝謝。向控制器注入服務

我的代碼包括模塊,服務和控制器的所有聲明/定義如下:

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


    myApp.factory('ListLogsFactory', function ($http) { 
      var thisPageNumber = 1; 
      var thisPageSize = 10; 
      var baseUrl = '../Api/LogApi/GetLogsByPage'; 

      var items = {}; 

      $http({ 
       method: 'GET', 
       url: baseUrl, 
       data: $.param({ pageNumber: thisPageNumber, pageSize: thisPageSize }) 
      }) 
      .success(function (data, status, headers, config) { 
       items = data; 
       console.log(items); 
      }) 
      .error(function (data, status, headers, config) { 
       alert('error: ' + status); 
      }); 

      function getData() { 
       return items; 
      } 
    }); 

    // The error is seen in FireFox and happens in the controller code: 
    myApp.controllers.ListLogsController = function ($scope, ListLogsFactory) { 
     $scope.logs = ListLogsFactory.getData(); // NOTE: this line throws error on running with something like "ListLogsFactory" is undefined 
    } 

回答

3

當您使用factory你必須返回的東西。你只是在那裏定義了一堆方法,但它們不適用於任何人。

使用不同的命名約定也很好。例如,而不是LogsController,使用LogsCtrl。 AngularJS在內部附加「Controller」,你可能會在異常情況下處理像「LogsControllerController」這樣的名字。

簡化approach of using factory and returning the service

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

ListLogsModule.factory('ListLogsSrv', function ($http) { 
    // first define the service (you're using a factory) 
    var getData = function() { 
     return "hey";//items; 
    }; 

    // then return it. 
    // offer a public method "getData" that uses your internal getData() 
    return { 
     getData : getData 
    } 
}); 

ListLogsModule.controller("ListLogsCtrl", function ($scope, ListLogsSrv) { 
    $scope.w = "world"; 
    $scope.logs = ListLogsSrv.getData(); 
}); 

您也可以在工廠的$http請求。這意味着您在實例化服務時(第一次使用服務時)會觸發異步請求,因此沒有人會等待它完成,並且您將獲得undefined。 如果您在控制器中使用此服務,您可能需要resolve承諾。

使用承諾的一個例子:

var promise = $q.defer(); 
var thisPageNumber = 1; 
... 
var baseUrl = '../Api/LogApi/GetLogsByPage'; 
... 
promise = $http.get(... 

現在你可以在控制器中使用了這個承諾,例如,或在你的服務的方法。

我回答一個相關的問題,前兩天Angular Service Definition: service or factory

+0

感謝您的回答。我在「服務」中應用了定義公共方法的方法,並且「ListLogsFactory未定義」的錯誤已經消失。但是,我看不到我的視圖頁面中的數據綁定。如何在控制器中使用「承諾」,以便數據綁定被推遲到從遠程服務器返回的數據準備好之前?在服務器端日誌中,我確實看到API RESTful方法已被調用並返回數據。 –

+0

可能是這樣的http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/簡單的方法是在'$ routeProvider'中使用控制器並使用'resolve' –

1
myApp.controllers.ListLogsController = function ($scope, ListLogsFactory) { 
     $scope.logs = ListLogsFactory.getData(); 
} 

應該

myApp.controller("ListLogsController", function ($scope, ListLogsFactory) { 
     $scope.logs = ListLogsFactory.getData(); 
}); 
+0

感謝您的回覆。我試圖用你的替代方法,但我仍然在FireFox中遇到同樣的錯誤。錯誤說「錯誤:ListLogsFactory未定義」。任何想法? –

+0

@ Thomas.Benz會在那裏添加一個console.log()以確保更新後的代碼已被讀取(ctrl + F5我相信也會強制刷新) – shaunhusain

1

以下是延長從@Eduard Gamonal的建議進行角向服務或工廠的變量/方法,因此它被認爲是一招要記住角服務的語法或工廠。

誘騙記憶「服務」或在角

服務栓與「服務」鍵字「工廠」的語法; 「這個」關鍵字使功能實例成員公開;和「=」來分配「功能實例成員」。

工廠結合「工廠」關鍵詞; 「return」關鍵字來創建/返回一個公共對象;和「」分配給所有鍵/值對分配。

詳情。

服務涉及「變量」(或「實例成員」),並使其「公」,我用的是「」關鍵字,並因爲「變量服務交易 「(或」實例成員「)公開我們在」變量「名稱之後使用」=「。

「getLogs」 可以像一個 「公共變量」 或 「實例成員」 像進行處理,並寫入(在 「分配」 之意)這個 .getLogs =函數(){...}。

而且整個服務與「服務」定義關鍵字:

<script type="text/javascript"> 
    var myApp = angular.module("ListLogsModule", []); 

    myApp.service('ListLogsService', function() { 


      this.getLogs = function() { 
       var logs = [ 
          {"LogId":5405,"RecordedDate" : "2012-11-19T14:22:02.247", "Event" : "Log On"}, 
          {"LogId":5416,"RecordedDate" : "2012-11-19T14:55:02.247", "Event" : "Log Out"} 
       ]; 
       return logs; 
      } 
    }); 


    myApp.controller('ListLogsCtrl', function ($scope, ListLogsService) { 
     $scope.logs = ListLogsService.getLogs();    
    }); 

</script> 

涉及返回的「對象」,並讓他們「公開」,我用的是「return」關鍵字,並且因爲工廠處理「對象」看起來像JSON對象我使用「」在「返回」語句{}內的每個「屬性」名稱後面。 (getLogs) function(){...}可以將「getLogs」視爲返回的JSON對象的屬性(或鍵),並寫入(在「鍵/值」對中)。

而整個工廠的「工廠」定義關鍵字:

<script type="text/javascript"> 
    var myApp = angular.module("ListLogsModule", []); 

    myApp.factory('ListLogsFactory', function() { 


      return { 
       getLogs: function() { 
        return[ 
           {"LogId":5405,"RecordedDate" : "2012-11-19T14:22:02.247", "Event" : "Log On"}, 
           {"LogId":5416,"RecordedDate" : "2012-11-19T14:55:02.247", "Event" : "Log Out"} 
        ]; 
       } 
      } 
    }); 


    myApp.controller('ListLogsCtrl', function ($scope, ListLogsFactory) { 
     $scope.logs = ListLogsFactory.getLogs(); 
    }); 

</script> 

總結:爲了紀念「服務」或角

服務「工廠」的語法綁用「服務」關鍵詞; 「這個」關鍵字使功能實例成員公開;和「=」來分配「功能實例成員」。

工廠結合「工廠」關鍵詞; 「return」關鍵字來創建/返回一個公共對象;和「」分配給所有鍵/值對分配。