admin管理员组文章数量:1404923
I am trying to get Masonry
working as an Angular directive, which is in part documented online, although I am having the following issues on 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 directive 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 also, crucially, how my scripts are layered 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 keep getting an error in the console which would suggest, I am not defining 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 am going wrong?
I would like to avoid using JQuery, possibly, as there is a newer Masonry available that doesn't use it.
I am trying to get Masonry
working as an Angular directive, which is in part documented online, although I am having the following issues on 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 directive 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 also, crucially, how my scripts are layered 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 keep getting an error in the console which would suggest, I am not defining 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 am going wrong?
I would like to avoid using JQuery, possibly, as there is a newer Masonry available that doesn't use it.
Share Improve this question edited Jun 18, 2013 at 13:45 Keren Caelen 1,4663 gold badges17 silver badges40 bronze badges asked Jun 18, 2013 at 12:58 JohnRobertPettJohnRobertPett 1,1834 gold badges22 silver badges37 bronze badges 6-
Have you tried loading
masonry.js
beforeapp.js
? (Putting its<script>
tag beforeapp.js
's in the file) – user2000008 Commented Jun 18, 2013 at 13:08 - Tried that, then it can't define the actual 'app' module. – JohnRobertPett Commented Jun 18, 2013 at 13:11
- The rabbit hole goes pretty deep mate - I ran into this problem myself recently. Have a look: stackoverflow./questions/16504151/masonry-with-angularjs – Dan Kanze Commented Jun 18, 2013 at 14:49
- That is what I started with and could never get the directive working in my app! A deep hole, indeed! – JohnRobertPett Commented Jun 18, 2013 at 15:11
- If you can see if this is replicating any of the errors you experience, please let me know: jsfiddle/ADukg/3154 – JohnRobertPett Commented Jun 18, 2013 at 15:52
2 Answers
Reset to default 4Ok, so after a serious hack/play, I have a solution for this: Where AngularJS is creating the view elements on the fly, there are many opportunities for error if the the 'ng-repeat' loads slower than the creation of masonry elements. I am sure there are more Angular style responses to this, but this allows for clean mark up and less Javascript needing to be written to achieve what is needed. Just add this code as a directive, add your child selector and then add 'masonry' to the parent div of the grid in your view:
'use strict';
app.directive('masonry', function ($parse) {
return {
link: function (scope, elem, attrs) {
setTimeout(function() {
$(".masonry").masonry({
itemSelector : ".masonry-item"
});
}, 0);
}
};
});
It looks like you are not actually applying the directive within 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 make isotope work in my app, let me know if this helps and if the error you are receiving changes.
Also try and add the column width statically inside your directive for now and see what happens. The error TypeError: Object [object Object] has no method 'masonry' might relate 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');
});
}
};
});
本文标签: javascriptAdding Masonry to Angular without JQueryStack Overflow
版权声明:本文标题:javascript - Adding Masonry to Angular without JQuery - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744859058a2628953.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论