Angular新手在这里。我试图找出将对象传递给指令时出了什么问题。
这是我的指示:
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
记录为undefined
,而scope
作为范围记录正常,甚至还有一个walks
子项,其中包含我要查找的所有数据
我不确定我在这里做错了什么,因为这个确切的方法以前对我有效。
编辑:
我创建了一个包含所有必需代码的plunker:http://plnkr.co/edit/uJCxrG
正如您所看到的,{{walks}}
在范围内可用,但我需要在链接功能中访问它,它仍然以未定义的方式记录。
答案 0 :(得分:40)
由于您使用$resource
来获取数据,因此指令的链接函数在数据可用之前运行(因为$resource
的结果是异步的),所以第一次在链接函数中scope.walks
将为空/未定义。由于您的指令模板包含{{}}
,因此Angular会在$watch
上设置walks
,因此当$resource
填充数据时,$watch
触发器和显示更新。这也解释了为什么您在控制台中看到散步数据 - 当您单击链接以扩展范围时,将填充数据。
要解决您的问题,请在链接功能$watch
中了解数据何时可用:
scope.$watch('walks', function(walks) {
console.log(scope.walks, walks);
})
在您的生产代码中,只需防止它未定义:
scope.$watch('walks', function(walks) {
if(walks) { ... }
})
更新:如果您使用的是$resource
支持承诺的Angular版本,请参阅@ sawe的回答。
答案 1 :(得分:11)
您也可以使用
scope.walks.$promise.then(function(walks) {
if(walks) {
console.log(walks);
}
});
答案 2 :(得分: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>
答案 3 :(得分: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));
}
}
});
答案 4 :(得分:0)
你声明的$ scope.store在控制器中是不可见的..你在一个函数中声明它。所以它只在该函数的范围内可见,你需要在外面声明:
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
}
});
});
});