如何将 Angular 范围用于服务请求和指令

How to use Angular scope with a service request and a directive

我有一个查询服务的控制器,如下所示:

app.controller('CandListCtrl', ['$scope', 'Cand',
  function ($scope, Cand) {

    Cand.query(function(data) {
      //data processing can happen here
      $scope.candidates = data;
    });

  }]);

我的服务查询 Google sheet:

var sheetServices = angular.module('candServices', []);

    sheetServices.factory('Cand', ['$rootScope',
      function($rootScope){
        return {
          query: function(callback) {
            Tabletop.init({
              key: '{{my key}}',
              simpleSheet: true,
              parseNumbers: true,
              callback: function(data, tabletop) {
                if(callback && typeof(callback) === "function") {
                  $rootScope.$apply(function() {
                    callback(data);
                  });
                }
              }
            });
          }
        };
      }]);

我的指令:

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

  return function (scope, element, attrs) {

      var events = scope.candidates;
      console.log(events); //undefined
 }
})

我在路由局部视图中使用时间线指令:

app.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/', {
        templateUrl: 'partials/cand-list.html',
        controller: 'CandListCtrl'
      }).
      otherwise({
        redirectTo: '/'
      });
  }]);

坎-list.html:

<div id="timeLine"><div timeline ng-style="myStyle"></div></div>

我的问题是我无法从我的指令中访问 $scope.candidates,因为它的范围仅限于查询函数。

我当然可以创建一个从函数中提取变量值的闭包。但这似乎不-Angular.

最好的前进方向是什么?

您可以使用事件发射器:

Cand.query(function(data) {
  // data processing can happen here
  $scope.candidates = data;
  // tell everyone that data is loaded
  $scope.$root.$broadcast('Cand.loaded', data);
});

在你的指令中:

app.directive('timeline', function () {
  return function (scope, element, attrs) {
    scope.$on('Cand.loaded', function(e, data) {
       var events = data;
       console.log(events); //defined
    });
  }
})

您需要学习如何沟通 b/w 指令和控制器 首先,您需要创建一个单独的指令范围,并允许它通过使用 '=','@'

从控制器范围访问数据

假设你的html是这样的:

<div>
   <timeline candidates="candidates"></timeline>
</div>

还有你的javascript:

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

  return {
    scope:{
      candidates:"="
    },

    link:function (scope, element, attrs) {
     scope.$watch('candidates', function() { 
              var events = scope.candidates; 
              console.log(events); 
         }) 
    }
  }
})

Exampledocumentation

上阅读更多关于指令的信息