2016-03-24 14 views
1

我目前使用的是Angular 1.3.14,並且我想在每次單擊鏈接時使用$ http發出請求。我試圖將$ http請求放入一個服務中,以便它不綁定到任何一個控制器,並且可以被多個控制器訪問。我創建了兩個函數sayHello()和getData()。點擊時我希望每個人都使用console.log。只有sayHello()函數,但不是getData()函數。這是我不明白的地方。

  1. 爲什麼$ http請求觸發加載,而不是點擊而sayHello函數完美工作?

  2. 我該如何修改我的代碼以便按預期工作?

    <p><a href="#" ng-click="getData()">Console Log Our Data</a></p> 
    <p> 
        <a href="#" ng-click="sayHello()">Console Log The Word "Hello"</a></p> 
    

    var app = angular.module('myApp', []) 
    
    .controller('mainCtrl', function($scope, dataService){ 
    
    $scope.sayHello = dataService.sayHello; 
    
    $scope.getData = dataService.getData(function(response){ 
         $scope.myData = response.data; 
        console.log($scope.myData); 
        }); 
    }) 
    .service('dataService', function($http){ 
    
    this.getData = function(callback){ 
         $http.get('http://jsonplaceholder.typicode.com/posts') 
         .then(callback); 
        } 
    
        this.sayHello = function(){ 
        console.log("Hello!"); 
        } 
    
    
    }); 
    

Codepen參考http://codepen.io/benweiser/pen/remvvo/

回答

1

當你做到這一點

$scope.getData = dataService.getData(function(response){ 
    $scope.myData = response.data; 
    console.log($scope.myData); 
}); 

})

dataService.getData立即執行。因此,$ scope.getData被設置爲一個承諾,而不是你想要綁定到ng-click的函數

更改這一行$ scope.getData = dataService.getData,它將實際設置一個函數回調至$ scope.getData

$scope.getData = dataService.getData.bind(this, function(response) { 
    $scope.myData = response.data; 
    console.log($scope.myData); 
}); 
+0

這與Maurcio的方法相反的優點還是缺點? –

+0

OP示例中的'this.getData'返回undefined,不是承諾 –

2

這是因爲$scope.getData等於不確定時,它應該是一個功能

$scope.getData = function() { 
    dataService.getData(function(response) { 
    $scope.myData = response.data 
    console.log($scope.myData) 
    }) 
} 

更新:您可以發送參數小號無論是從調用方法或從方法本身,假設你有以下的輸入

<input ng-model="name"> 

然後你就可以使用發送的值,並在服務中使用如下

<a ng-click="getData(name)">get data</a> 

$scope.getData = function (name) { 
    dataService.getData(name) 
    .then(function (response) { ... }) 
} 

或者直接使用它在控制器

<a ng-click="getData()">get data</a> 

$scope.getData = function() { 
    dataService.getData($scope.name) 
    .then(function (response) { ... }) 
} 

注意,這兩個假設dataService.getData()返回一個承諾,而不是通過回調,所以你想也需要做ÿ以下我們的服務,如果你想它像上面

this.getData = function (name) { 
    // do something with name 
    return $http.get('http://jsonplaceholder.typicode.com/posts/' + name) 
} 

你應該閱讀更多的承諾VS回調代碼以及如何利用它們:)

+0

謝謝你的完美工作。我會upvote,但沒有憑據。我可以使用這種方法傳遞參數嗎?比方說,我想從輸入中的ng-model中獲取數據,並通過服務中的URL傳遞數據?或者這是一個更好的控制器用例嗎?例如http://get_this_url.com/content.PARAMSFROMMODELHERE.json? –

+0

回答更新,你應該繼續閱讀@BenWeiser的基本面,https://github.com/angular/angular.js/wiki/Understanding-Scopes –

0

我會嘗試做這樣的事情。應該很容易適用於上面的代碼

//in your factory 
app.factory('dataFactory',function($http){ 

    factory = {}; 

    //get data 
    factory.getData = function(obj){ 
     return $http({ 
      method: 'GET', 
      url: 'http://jsonplaceholder.typicode.com/postsn' 
     }) 
    }; 

    return factory 
}); 

//in your controller 
app.controller(someCtrl,function($scope,dataFactory){ 

    dataFactory.getData().then(function(data){ 
     console.log('This will be your data: ', data) 
    }) 

}) 
+0

謝謝我還不完全瞭解我將要做的工廠打出文件來圍繞這個對比一個服務。 –

0

當控制器第一次加載時正在進行Ajax查詢。你的「getData」綁定不是用函數,而是用ajax調用,這就是爲什麼它沒有被觸發。

這個重構適用於codepen:

'use strict'; 

var app = angular.module('myApp', []) 

.controller('mainCtrl', function($scope, dataService){ 

    $scope.sayHello = dataService.sayHello; 

    $scope.getData = function(){ 
    dataService.getData().then(
     function(response){ 
      $scope.myData = response.data; 
       console.log($scope.myData); 
      } 
     ); 
    } 
}) 

.service('dataService', function($http){ 

    this.getData = function(callback){ 
     return $http.get('http://jsonplaceholder.typicode.com/posts'); 
    } 

    this.sayHello = function(){ 
     console.log("Hello!"); 
    } 

}); 

主要更新:

  1. $ scope.getData被綁定到一個函數,而不是一個Ajax調用/承諾
  2. 無極是外服(更好的解決方案,歡迎:-))。
  3. dataService.getData被稱爲函數。 (沒有以其他方式工作)。