角度范围.$ parent为空,错误或功能? [英] angular scope.$parent is null, a bug or a feature?

查看:68
本文介绍了角度范围.$ parent为空,错误或功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了以下代码,这是一条指令,该指令以无限自动滚动的方式显示来自服务器的数据,即,缩略图会自动向上滚动,并且每当拇指离开视图时,就会从服务器加载新的拇指.

I wrote the following code, which is a directive that display data from the server in an infinite autoscroll, i.e. the thumbnails are automatically scrolled up, and each time a thumb goes out of view a new one is loaded from the server.

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

If the user points on a thumb, the autoscroll stops until the user remove the mouse.

这行得通(只要用户没有将拇指指向手指),但是由于某种原因,在自动滚动停止后&重新启动,它会工作几秒钟,然后会中断,因为scope.$ parent为null

This works ok (as long as the user doesn't point on a thumb), but for some reason, after the autoscroll stops & restart, it works for a few seconds and then it breaks because the scope.$parent is null

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);

        }

    };


});

我的问题:

  1. 是否有更好的方法可以按照最佳角度实践?
  2. 为什么scope.$ parent节点变为空?是错误还是功能?
  3. 我该如何解决?

仅供参考:这是一个有效的代码-我使用rootScope而不是scope.$ parent

FYI: Here is a code that works - I use the rootScope instead of the 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链进行硬编码.例如,我注意到您正在查询band和bandsPage.您不必依赖于父作用域和继承来实现此目的,而可以使用作用域隔离将这些变量从父作用域映射到指令的隔离作用域中:

You asked about best practices. To make directives more flexible and reusable, it is recommended instead of hard-coding the $scope chain you inherit from the parent scope explicitly. For example, I noticed you are querying bands and bandsPage. Instead of relying on the parent scope and inheritance to make this possible, you can instead use scope isolation to map those variables from the parent scope into an isolated scope for your directive:

return {
   scope: {
       bands: "=", 
       bandsPage: "="
   },
   link: etc. etc. 
}

这将设置双向数据绑定,因此您可以像这样映射":

This sets up a two-way data-binding so you can "map-through" like this:

<myDirective bands="bands" bandsPage="bandsPage" ...> 

这样,无论您是在父作用域还是子作用域中,都不必捕获作用域值.它可以在链接上使用,但是只要使用该指令就可以在任何时候想要的东西,作用域隔离将自动为您的指令创建一个作用域,该作用域映射到您指定的继承属性,同时将代码与您没有的无关属性隔离开来.不需要.

This way it won't matter if you are in a parent scope or a child scope and you won't have to capture the scope value. It is available on linking but what you want is something there any time the directive is used, and the scope isolation will automatically create a scope for your directive that maps up to the inherited properties you specify while isolating your code from extraneous properties you don't need.

您可以在此处的隔离指令的范围"部分中了解更多信息:view-source:

You can learn more in the "Isolating the Scope of the Directive" section of the page here: view-source:http://docs.angularjs.org/guide/directive#!

这篇关于角度范围.$ parent为空,错误或功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆