在服务中使用Angular$http在ng点击时触发

Using Angular $http in a service to fire on ng-click

本文关键字:ng 服务 Angular http      更新时间:2023-09-26

我目前使用的是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!");
      }
    
    });
    

供参考的代码笔http://codepen.io/benweiser/pen/remvvo/

这是因为当$scope.getData应该是函数时,它等于undefined

$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()返回一个promise,而不是传递回调,因此如果您想像上面的一样对服务进行编码,则还需要对服务执行以下操作

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

您应该阅读更多关于Promises与回调的内容,以及如何利用它们:)

当您执行此时

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

})

dataService.getData立即执行。因此,$scope.getData被设置为promise,而不是您想要绑定到ng-click 的函数

将此行$scope.getData=dataService.getData更改为以下内容,这将实际将带回调的函数设置为$scope.getData

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

我会尝试这样做。应该很容易应用于以上的代码

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

首次加载控制器时进行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是作为一个函数调用的。(没有以其他方式工作)