Adding Freemasonry to Angular without jQuery

I am trying to get Masonry as an Angular directive, which is partially documented on the Internet, although I am having the following problems in the following code:

HTML code:

 <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 directory code:

 '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 Code:

 .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; } } } } 

Then it is also important how my scripts overlap in my index file:

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

I continue to receive an error message in the console, which could suggest that I did not define the masonry somewhere correctly:

 Uncaught TypeError: Cannot call method 'create' of undefined 

Then also:

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

Can anyone see where I'm wrong?

I would like to avoid using jQuery, perhaps since there is a new Freemasonry that does not use it.

+6
source share
2 answers

So, after a serious hack / game, I have a solution for this: where AngularJS creates presentation elements on the fly, there are many possibilities for error if "ng-repeat" loads slower than creating masonry elements. I am sure there are more stylish Angular answers for this, but it allows you to make a clean label and less Javascript that you need to write to achieve what you need. Just add this code as a directive, add a child selector, and then add โ€œfreemasonryโ€ to the parent grid div in your view:

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

It looks like you are not actually applying the directive in your 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> 

It took me a while to get the isotope to work in my application, let me know if this helps, and if the error you get has changed.

Also try and add the column width statically inside your directive, and see what happens. Error TypeError: Object [object Object] does not have a clutch method, may refer to 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'); }); } }; }); 
+1
source

Source: https://habr.com/ru/post/947550/


All Articles