Angularjs - 指令控制器加载速度比app控制器快 - 值未定义

时间:2014-03-04 01:31:20

标签: javascript ajax angularjs angularjs-directive angularjs-scope

我有一个控制器发出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
}
});

2 个答案:

答案 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>