角度指令碰撞

时间:2016-11-15 16:50:23

标签: angularjs angularjs-directive collision

我想在同一个应用程序中使用2个指令。问题是,当我使用第二个时,第一个崩溃时会出现一个丑陋的错误:TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'

第一个指令是angular-fullpage.js(https://github.com/hellsan631/angular-fullpage.js),第二个指令是角度引导词缀实现(https://github.com/maxisam/angular-bootstrap-affix)。

当我包含两个模块(指令)时,fullpage指令会因为上述错误而崩溃。如果我删除了affix指令,那么fullpage.js工作正常(只需从模块中删除第二个指令)。

如何避免指令碰撞?有没有针对这个问题的解决方法,或者我应该只解决其中一个指令?

感谢!!!!

app.js:

var myApp = angular
    .module(
    'myApp',
    [
        'ngRoute',
        'ngAnimate',
        'ngMessages',
        'ui.bootstrap',
        'angular-loading-bar',
        'LocalStorageModule',
        'ngEnter',
        'ng-Static-Include',
        'ngResource',
        'toastr',
        'ng-Static-Include',
        'pageslide-directive',
        'ngRutChange',
        'xmsbsStopPropagation',
        'ngEnter',
        'ng-rut',
        'ngMessages',
        'duScroll',
        'dynamicNumber',
        'xmsbsDirectives',
        'salfaDirectives',
        'mgcrea.bootstrap.affix',
        'fullPage.js',
        'ui.tinymce',
        'mega-menu',
        'bootstrap.fileField',
        'ngTagsInput'
    ]);

部分视图(主页)尝试使用fullpage指令并生成错误:

<div class="section">
    <div ng-style="{'width': '100%', 'height': vm.divHeight+'px'}" style="margin-top:-7px;background:url(/content/images/03.jpg) center center; background-size:cover;">
        <div class="col-sm-12">
            <h1 class="fg-grayLight text-center text-shadow vert-align-center" style="z-index:2;" ng-style="{'padding-top':vm.divHeight/9+'px'}">sistema de recursos humanos 2.0</h1>
        </div>
    </div>
</div>
<div class="section">
    <div class="col-sm-12">
        <h2 class="text-center">noticias</h2>
    </div>
</div>

词缀指令:

'use strict';

angular.module('mgcrea.bootstrap.affix', ['mgcrea.jquery'])

  .directive('bsAffix', function($window, dimensions) {

    var checkPosition = function(instance, el, options) {

      var scrollTop = window.pageYOffset;
      var scrollHeight = document.body.scrollHeight;
      var position = dimensions.offset.call(el[0]);
      var height = dimensions.height.call(el[0]);
      var offsetTop = options.offsetTop * 1;
      var offsetBottom = options.offsetBottom * 1;
      var reset = 'affix affix-top affix-bottom';
      var affix;

      if(instance.unpin !== null && (scrollTop + instance.unpin <= position.top)) {
        affix = false;
      } else if(offsetBottom && (position.top + height >= scrollHeight - offsetBottom)) {
        affix = 'bottom';
      } else if(offsetTop && scrollTop <= offsetTop) {
        affix = 'top';
      } else {
        affix = false;
      }

      if (instance.affixed === affix) return;

      instance.affixed = affix;
      instance.unpin = affix === 'bottom' ? position.top - scrollTop : null;

      el.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''));
    };

    var checkCallbacks = function(scope, instance, iElement, iAttrs) {
      if(instance.affixed) {
        if(iAttrs.onUnaffix)
          eval("scope." + iAttrs.onUnaffix);
      }
      else {
        if(iAttrs.onAffix)
          eval("scope." + iAttrs.onAffix);
      }
    };

    return {
      restrict: 'EAC',
      link: function postLink(scope, iElement, iAttrs) {
        var instance = {unpin: null};

        angular.element($window).bind('scroll', function() {
          checkPosition(instance, iElement, iAttrs);
          checkCallbacks(scope, instance, iElement, iAttrs);
        });

        angular.element($window).bind('click', function() {
          setTimeout(function() {
            checkPosition(instance, iElement, iAttrs);
            checkCallbacks(scope, instance, iElement, iAttrs);
          }, 1);
        });
      }
    };

  });

fullpage指令(此指令要求原始jQuery全页lugin工作http://www.alvarotrigo.com/fullPage/):

(function () {
    'use strict';

    angular
      .module('fullPage.js', [])
      .directive('fullPage', fullPage);

    fullPage.$inject = ['$timeout'];

    function fullPage($timeout) {
        var directive = {
            restrict: 'A',
            scope: { options: '=' },
            link: link
        };

        return directive;

        function link(scope, element) {
            var pageIndex;
            var slideIndex;
            var afterRender;
            var onLeave;
            var onSlideLeave;

            if (typeof scope.options === 'object') {
                if (scope.options.afterRender) {
                    afterRender = scope.options.afterRender;
                }

                if (scope.options.onLeave) {
                    onLeave = scope.options.onLeave;
                }

                if (scope.options.onSlideLeave) {
                    onSlideLeave = scope.options.onSlideLeave;
                }
            } else if (typeof options === 'undefined') {
                scope.options = {};
            }

            var rebuild = function () {
                destroyFullPage();

                $(element).fullpage(sanatizeOptions(scope.options));

                if (typeof afterRender === 'function') {
                    afterRender();
                }
            };

            var destroyFullPage = function () {
                if ($.fn.fullpage.destroy) {
                    $.fn.fullpage.destroy('all');
                }
            };

            var sanatizeOptions = function (options) {
                options.afterRender = afterAngularRender;
                options.onLeave = onAngularLeave;
                options.onSlideLeave = onAngularSlideLeave;

                function afterAngularRender() {
                    //We want to remove the HREF targets for navigation because they use hashbang
                    //They still work without the hash though, so its all good.
                    if (options && options.navigation) {
                        $('#fp-nav').find('a').removeAttr('href');
                    }

                    if (pageIndex) {
                        $timeout(function () {
                            $.fn.fullpage.silentMoveTo(pageIndex, slideIndex);
                        });
                    }
                }

                function onAngularLeave(page, next, direction) {

                    if (typeof onLeave === 'function' && onLeave(page, next, direction) === false) {
                        return false;
                    }
                    pageIndex = next;

                }

                function onAngularSlideLeave(anchorLink, page, slide, direction, next) {

                    if (typeof onSlideLeave === 'function' && onSlideLeave(anchorLink, page, slide, direction, next) === false) {
                        return false;
                    }
                    pageIndex = page;
                    slideIndex = next;

                }

                //if we are using a ui-router, we need to be able to handle anchor clicks without 'href="#thing"'
                $(document).on('click', '[data-menuanchor]', function () {
                    $.fn.fullpage.moveTo($(this).attr('data-menuanchor'));
                });

                return options;
            };

            var watchNodes = function () {
                return element[0].getElementsByTagName('*').length;
            };

            scope.$watch(watchNodes, rebuild);

            scope.$watch('options', rebuild, true);

            element.on('$destroy', destroyFullPage);
        }
    }

})();

1 个答案:

答案 0 :(得分:1)

第二个取决于第一个吗?如果是,你是否在嵌入第二个之前编译指令?

如果你有'碰撞',这意味着你正在使用某种'use strict',如果你展示部分代码并看看transclude是否是指令的一部分,那将更有价值。