我编写了以下代码,它是一个指令,以无限自动滚动的方式显示来自服务器的数据,即缩略图自动向上滚动,每次缩略图消失时都会从服务器加载一个新的。
如果用户指向拇指,则自动滚动停止,直到用户移开鼠标。
这可以正常工作(只要用户不指向拇指),但由于某种原因,在自动滚动停止并重新启动后,它会工作几秒钟,然后因为 scope.$parent 为空而中断
var wmApp = angular.module("wmApp");
wmApp.directive("wmThumb", function($rootScope, $http) {
return {
link: function(scope, element, attrs) {
$rootScope.autoscroll = 1;
w = $('.content').width();
h = $('.content').height();
eWidth = w * 0.2;
eHeight = h * 0.25;
growWidth = w * 0.4;
element.width(eWidth);
$(".bands-thumb").css("right", 0);
contain = element.parents(".thumbs-container");
element.css("margin", w * 0.01);
contain.height(h * 0.9);
contain.width(growWidth + 20);
contain.css("margin", w * 0.02);
$(".thumb-body", element).height(eHeight);
$(".thumb-pImg", element).height(eHeight);
$(".thumb-pImg img", element).width(eWidth);
$(".thumb-title", element).width(eWidth);
var startAutoScroll = function(elem) {
if ($rootScope.autoscroll <= 0
|| elem.height() == 0 /* elem is out of view*/
)
return;
var position = elem.position();
if (position.top < -elem.height()) {
//debugger;
// $rootScope.autoscroll--;
scope.$parent.bands.splice(0,1);
page = scope.$parent.bandsPage;
//$http.post('ui/list/Band', page).success(function(response) {
$.post('ui/list/Band', page, function (response) {
scope.$parent.bandsPage.count++;
scope.$parent.bands = scope.$parent.bands.concat(response);
// $rootScope.autoscroll++;
scope.$parent.$digest();
});
} else {
elem.animate({
top: "-=5"
}, 20, 'linear', function() {
startAutoScroll(elem);
});
}
};
setTimeout(function() {
ep= element.prev();
if (!ep.hasClass('node-thumb'))
t = 0;
else {
p = ep.position();
t = p.top;
t = t + element.height() + 5;
}
element.css("top", t + "px");
setTimeout(function() {
startAutoScroll(element);
}, 20);
}, 100);
growBody = growWidth - eWidth - 10;
element.bind("mouseenter", function() {
$(this).animate({
width: growWidth + 'px',
}, 100);
$(".thumb-body", element).show(100).animate({
width: growBody + 'px',
}, 100);
element.css("z-index", 100);
$rootScope.autoscroll--; // fix bug when jumping from each other
});
element.bind("mouseleave", function(event) {
$(this).animate({
width: eWidth + 'px',
}, 100);
$(".thumb-body", element).hide(100).animate({
width: '0px',
}, 100);
element.css("z-index", 1);
setTimeout(function() {
$rootScope.autoscroll++;
$(".node-thumb").each(function(i, e) {
e = $(e);
startAutoScroll(e);
});
}, 200);
});
setTimeout(function () {
element.show();
// // fit image id H is small
img = $(".thumb-pImg img", element);
imgH = $(img).height();
if (imgH < eHeight)
$(img).height(eHeight);
},100);
}
};
});
我的问题:
仅供引用:这是一个有效的代码 - 我使用 rootScope 而不是 scope.$parent
var wmApp = angular.module("wmApp");
wmApp.directive("wmThumb", function($rootScope, $http, $timeout) {
return {
link: function(scope, element, attrs) {
w = $('.content').width();
h = $('.content').height();
eWidth = w * 0.2;
eHeight = h * 0.25;
growWidth = w * 0.4;
element.width(eWidth);
$(".bands-thumb").css("right", 0);
contain = element.parents(".thumbs-container");
element.css("margin", w * 0.01);
contain.height(h * 0.9);
contain.width(growWidth + 20);
contain.css("margin", w * 0.02);
$(".thumb-body", element).height(eHeight);
$(".thumb-pImg", element).height(eHeight);
$(".thumb-pImg img", element).width(eWidth);
$(".thumb-title", element).width(eWidth);
var startAutoScroll = function(elem) {
if ($rootScope.autoscroll <= 0
|| elem.height() == 0 /* elem is out of view*/
)
return;
var position = elem.position();
if (position.top < -elem.height()) {
$rootScope.bands.splice(0,1);
page = $rootScope.bandsPage;
$.post('ui/list/Band', page, function (response) {
$rootScope.bandsPage.count++;
$rootScope.bands = $rootScope.bands.concat(response);
$rootScope.$digest();
});
} else {
elem.animate({
top: "-=5"
}, 20, 'linear', function() {
startAutoScroll(elem);
});
}
};
$timeout(function() {
ep= element.prev();
if (!ep.hasClass('node-thumb'))
t = 0;
else {
p = ep.position();
t = p.top;
t = t + element.height() + 5;
}
element.css("top", t + "px");
$timeout(function() {
startAutoScroll(element);
}, 20);
}, 100);
growBody = growWidth - eWidth - 10;
element.bind("mouseenter", function() {
$(this).animate({
width: growWidth + 'px',
}, 100);
$(".thumb-body", element).show(100).animate({
width: growBody + 'px',
}, 100);
element.css("z-index", 100);
$rootScope.autoscroll--; // fix bug when jumping from each other
});
element.bind("mouseleave", function(event) {
$(this).animate({
width: eWidth + 'px',
}, 100);
$(".thumb-body", element).hide(100).animate({
width: '0px',
}, 100);
element.css("z-index", 1);
$timeout(function() {
$rootScope.autoscroll++;
$(".node-thumb").each(function(i, e) {
e = $(e);
startAutoScroll(e);
});
}, 200);
});
$timeout(function () {
element.show();
// // fit image id H is small
img = $(".thumb-pImg img", element);
imgH = $(img).height();
if (imgH < eHeight)
$(img).height(eHeight);
},100);
}
};
});
最佳答案
您询问了最佳实践。为了使指令更加灵活和可重用,建议不要对从父范围继承的 $scope 链进行硬编码。例如,我注意到您正在查询bands 和bandPage。您可以使用范围隔离将这些变量从父范围映射到指令的隔离范围,而不是依赖父范围和继承来实现这一点:
return {
scope: {
bands: "=",
bandsPage: "="
},
link: etc. etc.
}
这设置了双向数据绑定(bind),因此您可以像这样“映射”:
<myDirective bands="bands" bandsPage="bandsPage" ...>
这样,您是在父作用域还是子作用域中都无关紧要,并且您不必捕获作用域值。它在链接时可用,但您想要的是任何时候使用该指令的东西,并且范围隔离将自动为您的指令创建一个范围,该范围映射到您指定的继承属性,同时将您的代码与您不使用的无关属性隔离开来不需要。
您可以在此处页面的“隔离指令的范围”部分了解更多信息:查看源代码:http://docs.angularjs.org/guide/directive# !
关于angularjs - angular scope.$parent 为空,是错误还是功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21404187/