在没有JQuery的情况下将Masonry添加到Angular

Joh*_*ett 6 javascript sass angularjs

我正在努力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>
Run Code Online (Sandbox Code Playgroud)

角度指令代码:

'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');
            });
        }
    };        
});
Run Code Online (Sandbox Code Playgroud)

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<script src="scripts/app.js"></script>
<script src="scripts/directives/masonry.js"></script>
<script src="scripts/controllers/main.js"></script>
Run Code Online (Sandbox Code Playgroud)

我一直在控制台中收到错误,这表明我没有正确地在某个地方定义砖石:

Uncaught TypeError: Cannot call method 'create' of undefined
Run Code Online (Sandbox Code Playgroud)

然后还:

TypeError: Object [object Object] has no method 'masonry'
Run Code Online (Sandbox Code Playgroud)

任何人都可以看到我错在哪里?

我想避免使用JQuery,因为有一个较新的Masonry可以使用它.

Joh*_*ett 4

好的,经过认真的 hack/play 后,我有一个解决方案:当 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);
        }
    };        
});
Run Code Online (Sandbox Code Playgroud)