我编写了以下代码,该代码是一个以无限自动滚动方式显示来自服务器的数据的指令,即缩略图会自动向上滚动,每次拇指离开视图时,都会从服务器加载新的缩略图。
如果用户指向拇指,则自动滚动停止,直到用户移除鼠标。
这样可行(只要用户没有指向拇指),但由于某种原因,在自动滚动停止后&重启,它工作几秒钟,然后它因为范围。$ 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而不是范围。$ 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);
}
};
});
答案 0 :(得分:3)
您询问了最佳做法。为了使指令更灵活和可重用,建议不要硬编码从父作用域明确继承的$ scope链。例如,我注意到你正在查询band和bandsPage。您可以使用范围隔离将父范围中的变量映射到指令的隔离范围,而不是依赖父范围和继承来实现此目的:
return {
scope: {
bands: "=",
bandsPage: "="
},
link: etc. etc.
}
这会设置双向数据绑定,因此您可以像这样“映射”:
<myDirective bands="bands" bandsPage="bandsPage" ...>
这样,无论您是在父作用域还是子作用域中,都无需捕获作用域值。它可以在链接时使用,但是在任何时候使用该指令时你想要的是什么,并且范围隔离将自动为你的指令创建一个范围,该范围映射到你指定的继承属性,同时将你的代码与你不相关的无关属性隔离开来。需要。
您可以在此处的“隔离指令范围”部分了解更多信息:view-source:http://docs.angularjs.org/guide/directive#!
答案 1 :(得分:0)
如果指令定义对象(DDO)的$parent
字段为假,则不会设置scope
成员。
return {
controller: 'myController',
link: function(scope, elm, attrs) {
// scope.$parent not set
return {
scope: true,
controller: 'myController',
link: function(scope, elm, attrs) {
// scope.$parent is set
这是因为scope
是私有范围的标志,因此,如果为false,则指令范围===控制器范围,因此$ parent范围是冗余的而不是设置。
当scope
设置为true
时,即使有$parent
成员,它的引用也不等于控制器范围,因此没有共享。
如果将scope
设置为定义getter属性的对象,则通过视图进行范围共享。
.controller('versionCntrlr', ['$scope', function($scope) {
$scope.scopeVersion = '0.2';
// ...
.directive(
// ...
return {
scope: { ver: '='},
controller: 'myController',
link: function(scope, elm, attrs) {
在视图中......
<span app-version ver="{{scopeVersion}}"></span>
因此,在这种情况下,您可以向控制器作用域添加一个值,它可供视图使用,由数据绑定提供,然后可以传递给指令。
似乎还有很多不同的替代排列,它们很奇怪,有时也很有用,但我猜这些排列应该是预期的。