让jQuery jPages插件与EmberJS和Ajax调用一起工作



我正在尝试让jPages与EmberJS一起工作。看起来jPages试图绑定到由于Ajax调用而没有及时加载的元素。有人让这个工作吗?这是jsfiddle:http://jsfiddle.net/stevenng/8hDRJ/33/

车把

<div class="songs">
    <script type="text/x-handlebars">
    {{#view Songs.songsView}}
        <div id="song-items">
        {{#each Songs.songsController}}
            <div class="song">
                <p>{{artist}}</p>                  
            </div>
        {{/each}}
        </div>
        <div class="pagination"></div>
    {{/view}}
    </script>
</div>​

JavaScript

Songs.songsController = Em.ArrayController.create({
    content: [],
    addSong: function(song) {
        this.pushObject(song);
    },
    getSongs: function() {
        var self = this;
        $.ajax({
            url: 'http://test.com/getSongs?callback=?',
            dataType: "jsonp",
            success: function(data){
              var obj = $.parseJSON(data);
              for (var i=0; i<obj.songs.length; i++) {
                self.addSong( Songs.song.create( obj.songs[i]) );    
              }
            }
        });
    }
});
Songs.songsView= Em.View.extend({
    didInsertElement: function() {
      $('.pagination').jPages({
        containerID: "song-items",
        perPage: 2
      });  
    }
});

正如您所说,当您实例化 jPages 插件时,歌曲元素尚未在 DOM 中。这就是为什么它不起作用的原因。

我的解决方案是在控制器上创建一个属性loaded。当设置为 true 时,视图知道内容已加载,并且可以实例化jPages,请参阅 http://jsfiddle.net/pangratz666/dpqCn/:

车把

<script type="text/x-handlebars" data-template-name="song" >
    {{content.artist}}
</script>​

JavaScript

Songs.songsController = Em.ArrayController.create({
    content: [],
    getSongs: function() {
        var self = this;
        $.ajax({
            success: function(data) {
                var songs = data.songs.forEach(function(song){
                    return Songs.Song.create(song);
                });
                // add all songs at once
                self.pushObjects(songs);
                // set the loaded property to true to indicate that the content is filled
                self.set('loaded', true);
            }
        });
    }
});
Songs.SongsView = Ember.ContainerView.extend({
    childViews: 'songsView paginationView'.w(),
    loadedBinding: 'controller.loaded',
    // invoked when the loaded property of the controller is changed
    _loadedChanged: function() {
        if (this.get('loaded')) {
            // get the songsView instance
            var songsView = this.get('songsView');
            // call jPages plugin on next run loop
            // when content has been filled and elements have been inserted to DOM
            Ember.run.next(this, function() {
                this.$('.holder').jPages({
                    containerID: songsView.get('elementId')
                });
            });
        }
    }.observes('loaded'),
    paginationView: Ember.View.create({
        classNames: 'holder'.w()
    }),
    songsView: Ember.CollectionView.create({
        contentBinding: 'parentView.controller.content',
        tagName: 'ul',
        itemViewClass: Ember.View.extend({
            templateName: 'song'
        })
    })
});

另一个注意事项:您的命名约定不符合 Ember 标准。请参阅Emberist的博客文章。因此类是UpperCase的,属性和实例是lowerCase的。

最新更新