我有一个控制器发出xhr请求来检索一些数据..
$scope.mbProductImages = [];
$http.get('product.json').success(function(data) {
$scope.productDetails = data;
$scope.mbProductImages = $scope['productDetails']['product_images'];
console.log($scope.mbProductImages);
for(key in $scope.mbProductImages){
if ($scope.mbProductImages[key].current == true) {
$scope.currentImage = $scope.mbProductImages[key]['img_lg'];
}
}
});
我真正需要的是一个指令,用于从控制器中加载的$scope.productDetails
(通过属性值)检索数据,我需要在指令的控制器或链接函数中使用此代码而不是$ parent控制器。 ..
$scope.mbProductImages = $scope[$attrs.content][$attrs.object];
console.log($scope.mbProductImages);
for(key in $scope.mbProductImages){
if ($scope.mbProductImages[key].current == true) {
$scope.currentImage = $scope.mbProductImages[key]['img_lg'];
}
}
其中指令中的$scope[$attrs.content][$attrs.object];
等同于来自控制器的$scope.productDetails
...
所以我的控制器应该只有这个:
$http.get('product.json').success(function(data) {
$scope.productDetails = data;
}
我的指令控制器会有其他代码。
我的傻瓜:http://plnkr.co/edit/xErYnlj04P5LQsMedVWi?p=preview
发生的情况是,获取数据的父控制器xhr请求所花费的时间比指令加载的时间要长,所以我留下了$scope.mbProductImages
未定义
如何让指令等待来自控制器的数据加载或检查从指令加载的时间然后应用值?
在@Chandermani的帮助下,我能够看到我的错误并找到了一个很好的解决方案。
控制器:
app.controller('MainCtrl', function($scope, $http) {
$http.get('mydata.json').success(function(data) {
$scope.productDetails = data;
console.log($scope.productDetails);
});
});
指令:
app.directive("myImages", function() {
return {
restrict: "E",
scope: true,
templateUrl: "template.html",
compile: function(element, attrs) {
return function(scope, element, attrs) {
scope.myContent = attrs.content;
scope.myObject = attrs.object;
scope.$watch(scope.myContent,function(newValue,oldValue){
if(newValue) {
scope.mbProductImages = newValue[scope.myObject];
console.log(scope.mbProductImages);
for(key in scope.mbProductImages){
if (scope.mbProductImages[key].current == true) {
scope.currentImage = scope.mbProductImages[key]['img_lg'];
}
}
}
})
}; // return
} // compile
}
});
答案 0 :(得分:7)
您没有指示等待,而是使用scope.$watch
观察范围变量的更改。
您的监视表达式应指向您要观看的属性。像
这样的东西$scope.$watch($attrs.content + $attrs.object, function(newValue,oldValue) {
if(newValue) {
//your logic here
}
});
watch的第一个参数应该是您要观察的对象属性的路径。
更新:我试图修复你的plunkr看看是否有帮助http://plnkr.co/edit/fKJ2nZcytKubC9JjiaTS?p=preview
我基本上把手表放在productDetails
财产上。
答案 1 :(得分:3)
如果您不想使用$watch
,可以使用ng-model将数据传递到指令中。在这种情况下,您的指令可能如下所示:
app.directive('myDirective',function(){
restrict: 'E',
require: 'ngModel',
link: function (scope, element, attrs, ngModel){
//called when controller change ngModel value
ngModel.$render = function(){
console.log('ngModel has changed');
//reading data from ngModel
scope.currentModelValue = ngModel.$modelValue;
processData()
}
function processData(){
//process your data
scope.currentModelValue = "new value";
updateModel();
}
function updateModel(){
//updating data
ngModel.$setViewValue(scope.currentModelValue)
}
}
});
HTML:
<my-directive ng-model="yourData"></my-directive>