在工厂内部获取$ get请求,在许多控制器上使用依赖注入时会触发两次?

时间:2014-06-19 18:04:51

标签: javascript angularjs dependency-injection get angularjs-scope

背景

我准备将我的角度项目连接到我的第一个API端点。我总是创建充满假JSON数据的工厂,所以这对我来说是新的。

HTML

第一个问题: 假设我们创建了两个范围。 1)由父控制器和2)由指令的控制器。如果我使用相同的页面服务注入两个范围,那么$ GET请求会触发两次吗?                 

angular.module('yoangApp')
 .directive('searchbar', function(){
  return {
    restrict: 'A',
    templateUrl: 'template1.html',
    controller: function($scope, Pages) {
      $scope.adPageData = Pages;
      $scope.adpageLength = $scope.adPageData.length;
    },
    link: function postLink(scope) {}
   }
});
angular.module('yoangApp')
 .controller('PageCtrl', function ($scope, Pages) {
  $scope.adPageData = Pages;
 }

页面工厂:

第二个问题 这个工厂写得好吗? 我无法访问api但我觉得语法错误。

var app = angular.module('yoangApp');
app.factory('Pages', function($http) {

    var Pages = {};
    $http.get('/api/page').success(function(pages) {
      Pages = pages;
    });
   return Pages;
});

来自/api/page

的示例对象
   'pages': [
     {name: 'wow1', imageurl: 'images/image1.jpg'}, 
     {name: 'wow2', imageurl: 'images/image2.jpg'}
     ]

3 个答案:

答案 0 :(得分:1)

我建议您的Pages工厂使用一种方法返回一个对象进行http GET调用:

var app = angular.module('yoangApp');
app.factory('Pages', function($http) {

    return {
        callApi: function(url, callback) {
            $http.get(url, callback);
        }
    };
});

然后可以使用它来设置adPageData范围属性,如下所示:

 angular.module('yoangApp')
     .controller('PageCtrl', function ($scope, Pages) {
        Pages.callApi('/api/page/', function(pagesResult) {
            $scope.adPageData = pagesResult;
        }
     });

这将解决#1,因为不会立即调用GET调用,并清除第2点的Pages工厂。

答案 1 :(得分:0)

有趣的问题。

1

工厂功能只会被调用一次。来自ng docs,

  

服务工厂函数生成单个对象或函数   表示对应用程序其余部分的服务。物体   或者服务返回的函数被注入到任何组件中   (控制器,服务,过滤器或指令)指定依赖项   在服务上。

因此,生成的对象/函数将被注入控制器。所以它不会发射两次。所有服务都是单身,每个应用程序实例化一次

For 2 - 理想情况下,即使在Pages返回响应之前,该函数也会返回http。因此,页面将始终为空。我想不是正确的方法来实现页面。

这是一个demo,它说明了这两点。

<强>解决方案: 作为一种解决方法,如果您希望自动更新响应,则从工厂返回一个对象,并从返回的对象访问页面,如下所示。

var pages = {data:null};
$http.get(/url).success(function(data){
pages.data = data;
});
return pages;

以下是更新后的demo来说明相同内容。 http调用仍然只会进行一次。

答案 2 :(得分:0)

1 - 您的指令中的任何内容都绑定到链接属性,一旦页面加载就会触发,如果您没有解决任何事件,例如点击 OR mouseover 或...到指令的元素属性。

** auto fire function : 

     link: function postLink(scope) {}
         console.log('I'm fired when page loads');
      }

** Binded to event function 

     app.directive('yourdirective',function(){
       return{
        restrict:"A" //OR "E"...
        link:function(scope,element,attributes){
          element.bind('click',function(){
            console.log('I'm fired when Someone clicks on this directive');
          });
        } 
       }

     })

2-我认为这可行,但是传统和首选的工厂写法是这样的:

       app.factory('Pages', function($http) {
           var Pages = {};
            return{
                getPages:function(){
                   $http.get('/api/page').success(function(pages) {
                       Pages = pages;
                        return Pages; 
                     });
                }
              }
       });