除非用angularjs刷新页面,如何修复指令中服务显示数据?

时间:2013-12-29 06:25:16

标签: angularjs

我有以下内容:

1 - MyService - a service that requests some data via $http
2 - MyDirective - a directive I want to show the data retrieved from the service

我的问题是,当我第一次加载页面时,从MyService检索到的数据似乎根本不会显示在指令中。当我重新加载页面时,它显示正常。所有后续重新加载都很好。

事件顺序如下:

1- Service fetches "data", a promise tracking when data comes back, then broadcasts a "ready" message to the directive.
2- Directive receives the "ready" with $on and puts the "data" somewhere viewable on the directive.

当我第一次访问网址时:

1- The directive shows up, but with none of the "data" from the service shows up.
2- Refresh the page/route
3- The directive shows up with the correct data.

由于检索,它似乎没有出现,但是当我在指令中注销$ on发射器时,似乎服务已成功接收数据并且它没有显示为“未定义”,但是未能真正将它们纳入指令......问题是什么?我怎么能解决它?

注意:

- The $on's that check for the ready event are in the directive's "controller:". 
- The directive's "link:" calls on the directive's "controller" methods for initialization (without any data from the service, as that logic is in the $on).

2 个答案:

答案 0 :(得分:0)

这是一个时间问题,当收到数据并触发事件时,您的指令 可能尚未构建 。当您重新加载页面时,它会起作用,因为您的指令模板可能会被缓存,从而构建 更快

我对此问题的解决方案是使用$ watch。下面是一些示例代码:

app.controller('MyController',function($scope, MyService){
     //Get data here using your MyService and assign to $scope.data
});

app.directive('MyDirective', function() {

return {
   restrict: 'EA',
   controller: function($scope) {
        $scope.$watch("data",function(newValue,OldValue,scope){
             //do your work here when data is changed.
        });  
      }
   };
};

如果使用隔离范围。尝试这样的代码:

app.controller('MyController',function($scope, MyService){
         //Get data here using your MyService and assign to $scope.data
    });

    app.directive('MyDirective', function() {

    return {
       restrict: 'EA',
       scope:{
          mydata:"="
       },
       controller: function($scope) {
            $scope.$watch("mydata",function(newValue,OldValue,scope){ //listen for mydata changes
                 //do your work here when data is changed.
            });  
          }
       };
    };

将绑定分配给html:

<div my-directive mydata="data"/>

答案 1 :(得分:0)

您似乎误解了服务的使用。服务不是自己加载数据,而是注入,并且调用由服务的调用者对象/控制器/指令完成。

虽然你没有发布你的问题似乎是服务代码,但是角度正在构建注入服务,但此时你已经开始$http调用并等待结果。当它到达时,您不知道谁需要数据,因为服务工厂始终是单身

以下应该始终有效,因为在编译指令并且处于链接阶段时,请求是发送。回调位于正确的位置,可以将结果设置为范围(实际上您想要的位置)。

随意编辑此..是我的想法,而不是错误检查

.factory('MyData', function($http) {
  var MyData = {};
  MyData.callData = function(method, url) {
    return $http(method, url);
  }
  return MyData;
})

.directive('myDirective', function(MyData) {
  return {
    restrict: 'E',
    link: function(scope, elem, attr) {
      MyData.callData('GET', '/something/useful')
        .success(function(data, status, headers, config) {
          $scope.items = data;
        });
    }
  }
});
<my-directive>
  <ul>
    <li ng-repeat="item in items">{{item}}</li>
  </ul>
</my-directive>

<强>更新 最好的方法是使用http://docs.angularjs.org/api/ngResource无论如何;)如果格式适用,但可以配置很多。在index.html中包含angular-resource.js,在应用程序中包含'ngResource'作为模块 - &gt;这是自1.2以来的新东西。