问题
I'm trying to get infinite scrolling and masonry working in my ember project. The masonry 'bricks' are posts with text and an image. Currently I can get the first page to show on the initial load of the page and apply masonry (I still have to do a setTimeout though, trying to figure out how to get rid of that as well).
I also have the basic infinite scroll code in. For now I'm simply grabbing the second page from the back end. When scrolled to the bottom of the page the second page of posts are loaded. What I'm trying to figure out is how to apply masonry to the new page upon insertion.
Putting $('#masonry-container').masonry('refresh')
in didInsertElement
doesn't work since the view element is already rendered and I'm simply appending new elements to the existing view.
Is there an event I can put the refresh in?
The code below applies masonry on the initial load and then loads the second page when scrolled to the bottom, but does not currently refresh masonry.
Thanks
Routing:
App.Router.map ->
@route 'posts', path: '/'
App.PostsRoute = Ember.Route.extend
model: ->
App.Post.find()
events:
more: ->
App.Post.query(page: 2) # hard code for now, next page will come from back end
View:
App.PostsView = Ember.View.extend
layoutName: 'appLayout'
templateName: 'posts'
controller: 'posts'
didInsertElement: ->
@scheduleMasony()
$(window).bind('scroll', =>
@.didScroll()
)
scheduleMasony: ->
Ember.run.schedule('afterRender', @, @applyMasonry)
applyMasonry: ->
setTimeout(->
$('#masonry-container').masonry(
itemSelector: '.box',
columnWidth: 220,
gutterWidth: 10,
isFitWidth: true,
isAnimated: true
)
2000)
didScroll: ->
if @isScrolledToBottom()
@get('controller').send('more')
isScrolledToBottom: ->
distanceToTop = $(document).height() - $(window).height()
top = $(document).scrollTop()
top == distanceToTop
Templates:
app_layout.handlebars
...layout mark up...
<div id="container">
{{yield}}
</div>
...more layout mark up...
posts.handlebars:
<div id="masonry-container" class="transitions-enabed infinite-scroll clearfix centered">
{{#each controller.content}}
<div class="col2 box">
<h3>{{title}}
<img {{bindAttr src="imageUrl"}} >
<p class="text">
{{text}}
</p>
</div>
{{/each}}
</div>
application.handlebars
{{outlet}}
回答1:
When scrolled to the bottom of the page the second page of posts are loaded. What I'm trying to figure out is how to apply masonry to the new page upon insertion.
I guess you are better of on observing the controller's content
length to re-invoke masonry since the appending to the DOM relates with the number of posts you are showing.
So try something like this:
App.PostsView = Ember.View.extend({
layoutName: 'appLayout'
templateName: 'posts'
controller: 'posts'
...
contentDidChange: function() {
// check for 'inDOM' just to be sure
// we don't run this unnecessarily
// when the view is not yet rendered
if(this.get('state') === "inDOM") {
applyMasonry();
}
}.observes('controller.content.length')
...
});
Hope it helps.
来源:https://stackoverflow.com/questions/18469748/ember-js-jquery-masonry-infinite-scroll