Javascript Angularjs-指令控制器加载速度快于应用程序控制器-值未定义
我有一个控制器,它发出xhr请求来检索一些数据Javascript Angularjs-指令控制器加载速度快于应用程序控制器-值未定义,javascript,ajax,angularjs,angularjs-directive,angularjs-scope,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.mbProd
$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 controller
$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]指令中的code>相当于控制器中的$scope.productDetails
$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'];
}
}
因此,我的控制器中应该只有以下内容:
$http.get('product.json').success(function(data) {
$scope.productDetails = data;
}
我的指令的控制器会有另一个代码
问题
我的笨蛋:
发生的情况是,获取数据的父控制器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
}
});
您不需要发出等待指令,而是使用scope.$watch
监视范围变量的更改
watch表达式应指向要监视的属性。差不多
$scope.$watch($attrs.content + $attrs.object, function(newValue,oldValue) {
if(newValue) {
//your logic here
}
});
watch的第一个参数应该是要监视的对象属性的路径
更新:我已尝试修复您的plunkr,看看是否有帮助
我基本上已经在productDetails
属性上放置了一个手表。如果您不想使用$watch
可以使用ng模型将数据传递到指令中。在这种情况下,您的指令可能如下所示:
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:
请设置一个plnkr.co。通常,一种方法是:
,其中值是要传递给指令的值。如果更改,请使用scope.$wait
$scope.$broadcast和$scope.$on。我很难设置plunker,因为我必须上传一组图像来树立榜样。。我正在努力。代码中的结果是间歇性加载,您可以使用维基百科中的公共图像。下面是plunker,它再现了我似乎遇到的问题,我一直在使用$watch函数。谢谢你。我一直试图观察一个物体,但我一直没有定义。然后我看到一篇文章,解释说你不能看整个物体。我的属性值永远不会更改。更改的是使用属性信息派生的对象的值。我需要注意$scope.mbProductImages
中的更改。。我假设我可以使用$scope.$watch('mbProductImages',函数(newValue,oldValue){if(newValue){//logic here},true)代码>我需要测试,我会拿着我得到的回来。最后,这是我的宝物:是的,这很有意义!谢谢我一直在尝试在新值真正改变之前改变它,并用它旋转。现在我也能够很好地传递属性数据。谢谢你指出这一点$手表的工作原理和我的情况完全一样,但是这个实现是我在NG模型的指令中考虑的。