我正在尝试创建一个指令来对子图像执行缩放。使用 ng-repeat 嵌入图像,URL 来自父 Controller 中的 REST API 调用。这是指令的嵌入:
这是该指令的模板:
<div>
<img image-directive-item ng-src="{{image.url}}" ng-style="{'width': {{image.width}}, 'height': {{image.height}}}" ng-if="image.done" />
</div>
要缩放每个图像,我需要有关其周围其他图像的宽度/高度的信息。目前,我正在尝试在绑定(bind)到图像的子指令中加载时将此信息传递给父级。这是我正在测试的代码:
angular.module("myApp")
.directive("imageDirective", function() {
return {
scope: { images: '=images'},
link: function(scope){
for(var i = 0; i < scope.images.length; i++) {
console.log(scope.images[i].width, scope.images[i].height);
}
},
templateUrl: _contextPath + 'static/html/imageDirective.html'
};
})
.directive("imageDirectiveItem", function() {
return {
link: function(scope, element) {
element.bind("load", function(e) {
scope.image.width = this.naturalWidth;
scope.image.height = this.naturalHeight;
});
}
};
});
图像正在页面上加载,并且加载回调可以读取尺寸,但是控制台中的输出(来自父指令)对于所有图像都是“未定义未定义”,并且出现有关无法设置尺寸的错误宽度/高度为空值。
我想以这种格式执行此操作,因为我需要按照图像在 DOM 中出现的顺序处理图像。然而,我正在努力让两者联系起来,而不需要诉诸黑客的手段。有什么想法吗?
下面由 New Dev 提供的解决方案对我有用。修改了元素传递给父指令的方式,以便它从加载回调传递对象,其中包含我需要的信息。今天学到了一些关于 Angular 的新知识!
angular.module("myApp")
.directive("imageDirective", function() {
return {
scope: { images: '=images'},
controller: function($scope){
var toBeLoaded = $scope.images.length;
this.childLoaded = function(childElement) {
console.log(childElement.naturalWidth, childElement.naturalHeight);
if(--toBeLoaded == 0) {
allChildrenLoaded();
}
};
function allChildrenLoaded() {
console.log("All children loaded.");
}
},
templateUrl: _contextPath + 'static/html/imageGrid.html'
};
})
.directive("imageDirectiveItem", function() {
return {
require: "^imageDirective",
link: function(scope, element, attrs, imageDirectiveCtrl) {
element.bind("load", function() {
var e = this;
scope.$apply(function() {
imageDirectiveCtrl.childLoaded(e);
});
});
}
};
});
控制台输出:
414 415
507 338
366 468
432 395
500 354
507 338
414 414
478 358
507 338
All children loaded.
最佳答案
您打印 undefined undefined
的原因是因为您在执行 for
循环时尚未加载任何图像。
如果您需要在父级中“处理”(如您所说)结果,那么在范围公开的对象上设置值可能不是最好的方法。例如,您如何知道它已完成加载?如果没有昂贵的深度$watch
,你怎么知道某些事情已经发生了变化?
我认为更好的方法是公开子指令可以调用的 API。这是通过在父 Controller 上公开一个函数并在子 Controller 上使用 require: "^imageDirective"
来完成的。
.directive("imageDirective", function(){
return {
// .. whatever you currently have
controller: function($scope){
var toBeLoaded = 0;
this.registerChild = function(childElem){
toBeLoaded++;
};
this.childLoaded = function(childElem){
toBeLoaded--;
// do whatever processing you need
};
}
}
})
.directive("imageDirectiveItem", function(){
return {
require: "^imageDirective",
link: function(scope, element, attrs, imageDirectiveCtrl){
imageDirectiveCtrl.registerChild(element);
element.bind("load", function(){
scope.$apply(function(){
imageDirectiveCtrl.childLoaded(element);
})
})
}
}
}
关于javascript - 加载内部指令后访问子元素图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29033286/