【问题标题】:cannot call methods on isotope prior to initialization; attempted to call method 'reLayout' angularjs无法在初始化之前调用同位素上的方法;试图调用方法'reLayout'angularjs
【发布时间】:2016-07-16 14:58:23
【问题描述】:

使用isotope 和prettyPhoto 以角度js 创建我的画廊视图,但得到错误无法在初始化之前调用同位素上的方法;试图调用方法“reLayout”我正在控制器中加载我的画廊视图,如下所示:

index.html

<ng-view></ng-view>

app.js

angular.module("myapp", ["ngRoute", "ui.bootstrap", "slickCarousel"]).
config(function($routeProvider, $locationProvider) {
  $routeProvider.
  when("/home", {
    templateUrl: "partial views/home.html"
  })
}).controller("portfolioController", function($scope, $location) {
  //Portfolio
  $scope.$watch("$viewContentLoaded", function() {
    "use strict";
    var $container = $('.portfolio'),
      $items = $container.find('.portfolio-item'),
      portfolioLayout = 'fitRows';

    if ($container.hasClass('portfolio-centered')) {
      portfolioLayout = 'masonry';
    }
    var init = false;
    $container.isotope({
      filter: '*',
      animationEngine: 'best-available',
      layoutMode: portfolioLayout,
      animationOptions: {
        duration: 750,
        easing: 'linear',
        queue: false
      },
      masonry: {}
    }, refreshWaypoints());

    function refreshWaypoints() {
      init = true;
      setTimeout(function() {}, 1000);
    }

    $('nav.portfolio-filter ul a').on('click', function() {
      var selector = $(this).attr('data-filter');
      $container.isotope({
        filter: selector
      }, refreshWaypoints());
      $('nav.portfolio-filter ul a').removeClass('active');
      $(this).addClass('active');
      return false;
    });

    function getColumnNumber() {
      var winWidth = $(window).width(),
        columnNumber = 1;

      if (winWidth > 1200) {
        columnNumber = 5;
      } else if (winWidth > 950) {
        columnNumber = 4;
      } else if (winWidth > 600) {
        columnNumber = 3;
      } else if (winWidth > 400) {
        columnNumber = 2;
      } else if (winWidth > 250) {
        columnNumber = 1;
      }
      return columnNumber;
    }

    function setColumns() {
      var winWidth = $(window).width(),
        columnNumber = getColumnNumber(),
        itemWidth = Math.floor(winWidth / columnNumber);

      $container.find('.portfolio-item').each(function() {
        $(this).css({
          width: itemWidth + 'px'
        });
      });
    }

    function setPortfolio() {
      setColumns();
      if (init) $container.isotope('reLayout');
    }

    $container.imagesLoaded(function() {
      setPortfolio();
    });

    $(window).on('resize', function() {
      setPortfolio();
    });
  });
})

home.html

<div id="portfoliowrap" ng-controller="portfolioController">
    <h3>LATEST WORKS</h3>
    <div class="portfolio-centered">
        <div class="recentitems portfolio">
            <div class="portfolio-item graphic-design">
                <div class="he-wrap tpl6">
                    <img src="/img/portfolio/portfolio_09.jpg" alt="">
                    <div class="he-view">
                        <div class="bg a0" data-animate="fadeIn">
                            <h3 class="a1" data-animate="fadeInDown">A Graphic Design Item</h3>
                            <a data-rel="prettyPhoto" href="assets/img/portfolio/portfolio_09.jpg" class="dmbutton a2" data-animate="fadeInUp"><i class="fa fa-search"></i></a>
                            <a href="single-project.html" class="dmbutton a2" data-animate="fadeInUp"><i class="fa fa-link"></i></a>
                        </div><!-- he bg -->
                    </div><!-- he view -->
                </div><!-- he wrap -->
            </div><!-- end col-12 -->
            <div class="portfolio-item books">
                <div class="he-wrap tpl6">
                    <img src="/img/portfolio/portfolio_10.jpg" alt="">
                    <div class="he-view">
                        <div class="bg a0" data-animate="fadeIn">
                            <h3 class="a1" data-animate="fadeInDown">A Book Design Item</h3>
                            <a data-rel="prettyPhoto" href="assets/img/portfolio/portfolio_10.jpg" class="dmbutton a2" data-animate="fadeInUp"><i class="fa fa-search"></i></a>
                            <a href="single-project.html" class="dmbutton a2" data-animate="fadeInUp"><i class="fa fa-link"></i></a>
                        </div><!-- he bg -->
                    </div><!-- he view -->
                </div><!-- he wrap -->
            </div><!-- end col-12 -->

        </div><!-- portfolio -->
    </div><!-- portfolio container -->
</div><!--/Portfoliowrap -->

如您所见,我还使用了$scope.$watch("$viewContentLoaded", 来确保已加载视图。但仍然超过错误。 Isotope 工作正常,但 prettyphoto 不能正常工作,这可能是因为这个错误。希望得到一些指导。

【问题讨论】:

  • 总是在指令中初始化插件。 $viewContentLoaded 不会向您保证所有渲染都已完成。控制器中不应该有任何与 dom 相关的代码。我相信已经有一个包裹同位素的角度模块...mankindsoftware.github.io/angular-isotope
  • @charlietfl.. 我会检查一次并通知.. :)
  • 也不要认为你可以用$watch 代替$viewContentLoaded,这是一个事件,你会使用$on。不顾一切的方法都是错误的......需要指令
  • @charlietfl.. 非常感谢.. 我已经解决了.. :)

标签: jquery angularjs jquery-isotope prettyphoto


【解决方案1】:

好吧,在 @charlietfl 的帮助下 - [非常感谢好友],我在 directives 的帮助下解决了这个问题。下面是示例代码。

app.js

angular.module("myapp", ["ngRoute", "ui.bootstrap", "slickCarousel"]).
config(function($routeProvider, $locationProvider) {
  $routeProvider.
  when("/home", {
    templateUrl: "partial views/home.html"
  })
}).controller("portfolioController", function ($scope, $location) {
    //Portfolio
    $scope.update = function () {
        $scope.imgList = [{
            url: "img/portfolio/portfolio_09.jpg",
            href: "assets/img/portfolio/portfolio_09.jpg",
            desc: "A Graphic Design Item"
        },
        {
            url: "/img/portfolio/portfolio_02.jpg",
            href: "assets/img/portfolio/portfolio_02.jpg",
            desc: "A Web Design Item"
        },
        {
            url: "/img/portfolio/portfolio_03.jpg",
            href: "assets/img/portfolio/portfolio_03.jpg",
            desc: "A Web Design Item"
        }];
    }
    $scope.update();
}).directive('isoRepeat', function ($timeout) {
    return {
        scope: {
            items: '=isoRepeat'
        },
        template: '<div class="portfolio-item graphic-design" ng-repeat="item in items"><div class="he-wrap tpl6"><img ng-src="{{item.url}}" /><div class="he-view">'
                  + '<div class="bg a0" data-animate="fadeIn">'
                  + '<h3 class="a1" data-animate="fadeInDown">{{item.desc}}</h3>'
                  + '<a data-rel="prettyPhoto" ng-href="{{item.href}}" class="dmbutton a2" data-animate="fadeInUp"><i class="fa fa-search"></i></a>'
                  + '<!--<a href="single-project.html" class="dmbutton a2" data-animate="fadeInUp"><i class="fa fa-link"></i></a>-->'
                  + '</div><!-- he bg -->'
                  + '</div><!-- he view -->'
                  + '</div><!-- he wrap --></div><!-- end col-12 -->',
        link: function (scope, element, attrs) {

            var options = {
                filter: '*',
                animationEngine: 'best-available',
                itemSelector: '.portfolio-item',
                layoutMode: 'fitRows',
                animationOptions: {
                    duration: 750,
                    easing: 'linear',
                    queue: false
                }
            };

            element.isotope(options);
            scope.getColumnNumber = function () {
                var winWidth = $(window).width(),
                columnNumber = 1;

                if (winWidth > 1200) {
                    columnNumber = 5;
                } else if (winWidth > 950) {
                    columnNumber = 4;
                } else if (winWidth > 600) {
                    columnNumber = 3;
                } else if (winWidth > 400) {
                    columnNumber = 2;
                } else if (winWidth > 250) {
                    columnNumber = 1;
                }
                return columnNumber;
            }

            scope.setColumns = function () {
                var winWidth = $(window).width(),
                columnNumber = scope.getColumnNumber(),
                itemWidth = Math.floor(winWidth / columnNumber);

                $(element).find('.portfolio-item').each(function () {
                    $(this).css({
                        width: itemWidth + 'px'
                    });
                });
            }

            scope.setPortfolio = function () {
                scope.setColumns();
                $(element).isotope('reLayout');
            }
            $(window).on('resize', function () {
                scope.setPortfolio();
            });
            scope.$watch('items', function (newVal, oldVal) {
                $timeout(function () {
                    element.isotope('reloadItems').isotope();
                    scope.setPortfolio();
                });
            }, true);
        }
    };
});

home.html

<div class="recentitems portfolio" data-iso-repeat="imgList">
</div><!-- portfolio -->

【讨论】:

  • 看起来好多了。可能还想删除 scope.$on('$destroy', func... 中的窗口侦听器
  • @charlietfl.. 抱歉.. 从哪里来??
  • 内部指令scope.$on('$destroy', function(){ $(window).off('resize');})。如果页面其他地方使用的其他调整大小也可以命名该事件
  • 继续...如果问为什么要删除它,它可能并不重要,但在页面的整个生命周期中都会存在,即使切换路由时元素会消失。当它仅适用于特定路线中的部分页面时,必须对 $interval 之类的东西做同样的事情
  • 哦,是的.. 清除了@charlietfl.. 我在锚中使用data-rel,而我应该使用rel.. 再次感谢.. :) 快乐编码.. :)
猜你喜欢
  • 1970-01-01
  • 2020-02-03
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-30
相关资源
最近更新 更多