29

角新手在这里。我试图弄清楚在将对象传递给指令时出了什么问题。

这是我的指令:

app.directive('walkmap', function() { 
  return {
    restrict: 'A',
    transclude: true,
    scope: { walks: '=walkmap' },
    template: '<div id="map_canvas"></div>',
    link: function(scope, element, attrs)
    {
      console.log(scope);
      console.log(scope.walks);
    }
  };
});

这是我调用指令的模板:

<div walkmap="store.walks"></div>

store.walks是一个对象数组。

当我运行它时,scope.walks将日志记录为undefinedwhilescope日志很好,作为 Scope 甚至有一个walks包含我正在寻找的所有数据的孩子。

我不确定我在这里做错了什么,因为这种确切的方法以前对我有用。

编辑:

我用所有必需的代码创建了一个 plunker:http: //plnkr.co/edit/uJCxrG

如您所见,{{walks}}它在范围内可用,但我需要在仍将其记录为未定义的链接函数中访问它。

4

5 回答 5

40

由于您$resource用于获取数据,指令的链接函数在数据可用之前运行(因为结果$resource是异步的),因此链接函数中的第一次scope.walks将为空/未定义。由于您的指令模板包含{{}}s,Angular 设置了$watchon walks,因此当$resource填充数据时,$watch触发器和显示会更新。这也解释了为什么您会在控制台中看到步行数据——当您单击链接以扩大范围时,数据已被填充。

要解决您的问题,请在您的链接功能$watch中了解数据何时可用:

scope.$watch('walks', function(walks) {
   console.log(scope.walks, walks);
})

在您的生产代码中,请注意不要将其未定义:

scope.$watch('walks', function(walks) {
  if(walks) { ... }
})

更新:如果您使用$resource支持承诺的 Angular 版本,另请参阅@sawe 的回答。

于 2013-01-31T21:04:57.437 回答
12

你也可以使用

scope.walks.$promise.then(function(walks) {
    if(walks) {
      console.log(walks);
    }
  });
于 2013-10-18T12:39:34.953 回答
3

另一种解决方案是添加ControllerAs到指令中,您可以通过它访问指令的变量。

app.directive('walkmap', function() { 
  return {
    restrict: 'A',
    transclude: true,
    controllerAs: 'dir',
    scope: { walks: '=walkmap' },
    template: '<div id="map_canvas"></div>',
    link: function(scope, element, attrs)
    {
      console.log(scope);
      console.log(scope.walks);
    }
  };
});

然后,在您看来,使用变量传递controllerAs变量。

<div walkmap="store.walks" ng-init="dir.store.walks"></div>
于 2014-12-18T13:28:17.583 回答
2

尝试:

<div walk-map="{{store.walks}}"></div>

angular.module('app').directive('walkMap', function($parse) {
  return {
    link: function(scope, el, attrs) {
      console.log($parse(attrs.walkMap)(scope));
    }
  }
});
于 2015-04-12T23:23:57.793 回答
0

your declared $scope.store is not visible from the controller..you declare it inside a function..so it's only visible in the scope of that function, you need declare this outside:

app.controller('MainCtrl', function($scope, $resource, ClientData) {
  $scope.store=[];         // <- declared in the "javascript" controller scope
  ClientData.get({}, function(clientData) {
  self.original = clientData;
  $scope.clientData = new ClientData(self.original);
  var storeToGet = "150-001 KT";
  angular.forEach(clientData.stores, function(store){
   if(store.name == storeToGet ) {
     $scope.store = store;      //declared here it's only visible inside the forEach
     }
   });
  });
 });
于 2013-01-31T17:22:27.377 回答