angularjs - angular scope.$parent 为空,是错误还是功能?

标签 angularjs

我编写了以下代码,它是一个指令,以无限自动滚动的方式显示来自服务器的数据,即缩略图自动向上滚动,每次缩略图消失时都会从服务器加载一个新的。

如果用户指向拇指,则自动滚动停止,直到用户移开鼠标。

这可以正常工作(只要用户不指向拇指),但由于某种原因,在自动滚动停止并重新启动后,它会工作几秒钟,然后因为 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);

        }

    };


});

我的问题:
  • 根据 Angular 最佳实践,有没有更好的方法来做到这一点?
  • 为什么 scope.$parent 节点变为空?它是错误还是功能?
  • 我应该如何解决这个问题?

  • 仅供引用:这是一个有效的代码 - 我使用 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/

    相关文章:

    javascript - 使用 Angular 获取数据 API 调用时出错

    javascript - 无法在组件内部使用 [routerLink]

    javascript - 条件 AngularJS 模型绑定(bind)

    javascript - 如何获得 ng-list 行为,但模型略有不同?

    javascript - 使用 $httpBackend 接收二进制响应的单元测试

    javascript - Angular 数据表有时无法加载

    javascript - 如何更改AngularJS中的输入类型

    带有 ng-repeat 的 AngularJS 指令不呈现

    javascript - 如何配置 Angular ui-router 不使用严格的 URL 匹配模式

    javascript - 将数据从输入字段传递到 Angular 工厂中的 $http.get