【问题标题】:Adding Masonry to Angular without JQuery在没有 JQuery 的情况下将砌体添加到 Angular
【发布时间】:2013-06-18 12:58:06
【问题描述】:

我正在尝试让 Masonry 作为 Angular 指令工作,该指令部分记录在网上,尽管我在以下代码中遇到以下问题:

HTML 代码:

<div ng-controller="GridCtrl" class="grid-wrapper">
    <div class="masonry">
        <div ng-repeat="item in gridItems" ng-class="item.class">
            <h3>{{item.name}}</h3>
            <img ng-src="{{item.image}}"/>
            <br>
            <button ng-repeat="button in item.buttons">{{button.text}}</button>
        </div>
    </div>
</div>

Angular 指令代码:

'use strict';

angular.module('HomeCourtArenaApp').directive('masonry', function ($parse) {
    return {
        restrict: 'AC',
        link: function (scope, elem, attrs) {
            elem.masonry({ itemSelector: '.masonry-item', columnWidth: $parse(attrs.masonry)(scope) });
        }
    };        
});

angular.module('HomeCourtArenaApp').directive('masonryItem', function () {
    return {
        restrict: 'AC',
        link: function (scope, elem, attrs) {
            elem.imagesLoaded(function () {
               elem.parents('.masonry').masonry('reload');
            });
        }
    };        
});

SCSS 代码:

.grid-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    padding-left: 40%;
    overflow-x: scroll;
    overflow-y: hidden;
    .masonry {
        position: absolute;
        width: 2600px;
        max-height: 1080px;
        .masonry-item,
        .poster {
            float: left;
            width: 465px;
            padding: 15px;
            margin: 12px 12px 0 0;
            box-shadow: 1px 1px 4px 3px rgba(55,55,55,0.25);
        }
        .masonry-item {
            background: #fafafa;
            height: 295px;
            h3 {
                width: 100%;
                text-align: left;
                font-size: 28px;
                color: #3D444A;
                display: block;
            }
            img {
                display: block;
                padding: 50px 0 10px;
                margin: 0 auto;
            }
        }
        .poster {
            height: 631px;
            background: #000;
            position: relative;
            h3 {
                color: #fff;
                font-family: 'adineuebold';
                font-size: 68px;
                position: absolute;
                top: 410px;
                left: 20px;
                z-index: 2;
            }
            img {
                position: absolute;
                left: 0;
                top: 0;
                z-index: 1;
                margin: 0;
                padding: 0;
            }
            button {
                position: absolute;
                z-index: 2;
                left: 20px;
                top: 590px;
            }
        }
        button {
            padding: 12px 15px;
            font-size: 15px;
            margin-right: 10px;
            font-family: 'adihausregular';
            color: #fff;
            text-transform: uppercase;
            border: none;
            background: linear-gradient(to bottom,  rgba(57,134,202,1) 0%,rgba(3,75,146,1) 100%);
            &:after {
                content: "";
                background: url('img/sprite.png') no-repeat -156px -9px;
                width: 16px;
                height: 16px;
                margin-left: 30px;
                display: inline-block;
            }
        }
    }
}

然后,至关重要的是,我的脚本在我的索引文件中是如何分层的:

<script src="scripts/app.js"></script>
<script src="scripts/directives/masonry.js"></script>
<script src="scripts/controllers/main.js"></script>

我在控制台中不断收到错误提示,我没有正确定义某处的砌体:

Uncaught TypeError: Cannot call method 'create' of undefined

然后:

TypeError: Object [object Object] has no method 'masonry'

谁能看出我哪里出错了?

我可能想避免使用 JQuery,因为有一个更新的 Masonry 可用,但不使用它。

【问题讨论】:

  • 您是否尝试在app.js 之前加载masonry.js? (在文件中将其&lt;script&gt; 标签放在app.js 之前)
  • 试过了,然后它无法定义实际的“应用”模块。
  • 兔子洞很深,我最近自己也遇到了这个问题。看看:stackoverflow.com/questions/16504151/masonry-with-angularjs
  • 这就是我开始的方式,并且永远无法让指令在我的应用程序中工作!确实是个深洞!
  • 如果您可以查看这是否复制了您遇到的任何错误,请告诉我:jsfiddle.net/ADukg/3154

标签: javascript angularjs sass


【解决方案1】:

好的,所以经过认真的破解/播放后,我有一个解决方案:AngularJS 在动态创建视图元素的地方,如果“ng-repeat”加载速度比创建速度慢,则有很多错误机会砌体元素。我确信对此有更多 Angular 风格的响应,但这允许进行干净的标记,并且需要编写更少的 Javascript 来实现所需的内容。只需将此代码添加为指令,添加您的子选择器,然后将“masonry”添加到视图中网格的父 div:

'use strict';

app.directive('masonry', function ($parse) {
    return {
        link: function (scope, elem, attrs) {   
            setTimeout(function() {
                $(".masonry").masonry({
                    itemSelector : ".masonry-item"
                });
            }, 0);
        }
    };        
});

【讨论】:

  • 尝试此操作时仍然从砖石获得Cannot call method 'create' of undefined。您能否提供更多代码说明您是如何在视图中实现这一点的?
  • 脚本在 index.html 文件中的顺序是什么?我会为你挖掘我的代码。
  • setTimeout,真的吗? $(".masonry"),认真的吗?
【解决方案2】:

看起来您实际上并未在 html 中应用该指令。

<div ng-controller="GridCtrl" class="grid-wrapper">
    <div class="masonry" masonry>
        <div ng-repeat="item in gridItems" ng-class="item.class" masonry-item>
            <h3>{{item.name}}</h3>
            <img ng-src="{{item.image}}"/>
            <br>
            <button ng-repeat="button in item.buttons">{{button.text}}</button>
        </div>
    </div>
</div>

我花了一段时间才让同位素在我的应用中工作,如果这有帮助,请告诉我你收到的错误是否发生了变化。

现在还可以尝试在指令中静态添加列宽,看看会发生什么。错误 TypeError: Object [object Object] has no method 'masonry' 可能与 attrs.masonry 相关:

angular.module('HomeCourtArenaApp').directive('masonry', function ($parse) {
    return {
        restrict: 'AC',
        link: function (scope, elem, attrs) {
            elem.masonry({ itemSelector: '.masonry-item', columnWidth: 200 });
        }
    };        
});

angular.module('HomeCourtArenaApp').directive('masonryItem', function () {
    return {
        restrict: 'AC',
        link: function (scope, elem, attrs) {
            elem.imagesLoaded(function () {
               elem.parents('.masonry').masonry('reload');
            });
        }
    };        
});

【讨论】:

  • 感谢您的回答。我假设我不必将该指令应用于 HTML,因为它已链接到类。我已经添加了您建议的方法,它会引发更多错误。我想我没有在应用程序中正确声明指令:除了 index.html 文件中的脚本标记之外,控制器 HTML 中的指令代码和引用我是否遗漏了什么?
  • 您还遇到了哪些其他错误?指令应用在您想要使用它们的 html 标记中。这就是指令的重点。然后指令中的变量元素包含对该 html 元素的引用
  • 这些:TypeError: Object [object Object] has no method 'imagesLoaded' | TypeError: Object [object Object] 没有方法'masonry' |未捕获的类型错误:无法调用未定义的方法“创建”
  • Oki,所以我为您修复了它,但是没有 jquery 就无法使其工作:jsfiddle.net/Dz5uT/4 SOZ!也许其他人会想出一个不需要 jquery 的更好的解决方案 - 有了这个解决方案,你也可以使用 imagesloaded 插件
  • 试一试:jsfiddle.net/Dz5uT/14 Masonry 似乎期望容器中至少有一个元素。然而,在砌体安装时,情况并非如此,因为重复运行。因此我会在 masonry-item 指令中初始化 masonry。
猜你喜欢
  • 2016-12-28
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
  • 2012-11-06
相关资源
最近更新 更多