在哪里操纵通过AJAX服务获得的数据?链接fn或控制器?

时间:2016-03-18 18:08:10

标签: javascript angularjs ajax model-view-controller

我有一个HTML部分,我也试图绑定AJAX数据。出于某种原因,似乎我必须将AJAX服务调用放在指令的link函数中。我不能把它放在控制器中;我在这样的指令中这样做:

link: function(scope){
  MyService.getData().then(function(res){
    scope.myData = res.data;
  }, function(res){
    throw new Error('Error getting data');
  });
}

首先,我很好奇为什么我不能在我的控制器中执行此操作。但是,一旦我得到它,我想对数据进行一些操作。是否所有这些都需要在链接函数中发生。在控制器中循环$scope.myData将无法正常工作,因为它尚未定义?我可以以某种方式在我的控制器中使用我的AJAX数据,而无需在链接文件中执行我的逻辑吗?

5 个答案:

答案 0 :(得分:7)

任务可以通过各种方式完成,但问题是哪种做法最好。 首先,如果你有一个部分指令,你想绑定它,你可以在指令的控制器中做到这一点

app.directive('myPartial', function() {
  return {
    restrict:'AE',
    template:'<pre>[{{myData| json}}]</pre>',
    scope:true,   
    link:function(scope, elem, attrs) {
      /*avoid using model manipulation in link function as it is mostly used 

      for DOM manipulation such as angular.element(elem).addClass('myTemplateClass');*/
    },
    controller: function($scope,MyService){
         MyService.getData().then(function(dataFromServer){
             scope.myData = dataFromServer;
         }, function(err){
            throw new Error('Error getting data : ' + err);
         });
    }
  };
});

使用AngularJS时,您必须拥有 THIN 控制器和 THICK 服务..如果您需要操纵数据。在服务中执行此操作并将此类形式的数据返回到可直接分配给控制器的控制器。这是最好的做法。即在你的服务中。这样做

app.factory('MyService',function($http,$q){

     var _modifyGetData = function(serverData){
        // modify your data here...
        // for example -> serverData.usersCount = serverData.users.length;
        return serverData;
     };
     var getData = function(){
         var dfd = $q.defer();
         $http.get(/*Some url here*/).then(function(res){
              var data = res.data;
              // manipulate all your data using a function maybe
              data = _modifyGetData(data);
              dfd.resolve(data);   //resolve the modified data


         });
         return dfd.promise;
     }
     return {
        getData:getData
     };
});

希望这有帮助。

可能有所帮助的一些在线资源: https://scotch.io/tutorials/making-skinny-angularjs-controllers https://teamgaslight.com/blog/4-lessons-learned-doing-angular-on-rails

答案 1 :(得分:0)

您是如何将它放入控制器的?我的控制器中有一个函数,我通过ng-init调用,以加载我的数据。基于您的代码段的示例:

.controller('myCtrl', function ($scope, MyService) {
        $scope.initData = function(){
            MyService.getData().then(function(res){
                $scope.myData = res.data;
              }, function(res){
                throw new Error('Error getting data');
              });
        }
}

然后在我的部分中,在我的一个HTML标签中:

<div ng-init="initData()"></div>

只需将ng-init添加到您的一个HTML标记即可发送呼叫。不确定它是否正确,但它适用于我的场景,也适用于你的场景。

答案 2 :(得分:0)

显然有几种方法可以实现这一目标;根据您的需要,有些可能比其他人更好。我建议您更多地考虑从服务中获取的数据及其所属的数据。

  1. 如果该数据仅由指令维护,那么您应该继续按照链接函数的方式保存代码。您将数据及其操作封装在指令中。 (显然这个选项对你的案子不起作用,但我只是在解释何时这可能有意义)
  2. 如果只需要由您的单个控制器访问该数据,则可以从您的指令公开范围绑定,无论是单向还是双向以满足您的需求(请参阅&#34;隔离范围指令&#34; this page)。通过这种方式,您可以获取控制器中的数据并将其传递到指令中,以便操作&#34;操作&#34;上。
  3. 如果该数据是多个指令和控制器需要访问的数据,则它应该完全存在于服务本身中。通过这种方式,如果控制器或指令访问数据,因为它们都看到相同的数据,这并不重要。显然你的问题是关于ajax调用,所以你需要为你的服务建立一个缓存机制(查看this)。
  4. 无论哪种方式,您都应该使用上面的(3)来提供服务。在处理本地缓存时要注意陷阱。 希望这会有所帮助。

    编辑: 如果您正在寻找编码示例,请告诉我 - 您的问题似乎更多关于&#34;我的选择是什么&#34;而不是具体的技术实施细节。

    干杯!

答案 3 :(得分:0)

您可以从控制器中调用该服务。

你不能的原因是什么?

YourController.$inject = ['MyService', '$scope'];
function YourController(myService, $scope) {

    myService.getData().then(
        function(res) { 
            $scope.myData = res.data;
            // or manipulate the data
            $scope.apply(); 
        })
}

答案 4 :(得分:0)

您可以在指令的控制器中执行此操作,例如:

app.directive('output', function() {
  return {
    retrict:'E',
    replace:true,
    template:'<pre>[{{MyData | json}}]</pre>',
    scope:true,
    controller:function(MyService, $scope) {
      $scope.MyData = $scope.MyData || {};
      MyService.getData().then(function(value){
        $scope.MyData.value = value;
      });
    },
    link:function(scope, element, attrs) {
      scope.MyData = scope.MyData || {};
    }
  };
});

看到这个小提琴:http://jsfiddle.net/oq2m149e