如何从 Backbone 视图在动态客户端模板中呈现 jQuery Mobile?

How to render jQuery Mobile in dynamic clientside templates from a Backbone view?

我正在使用 Brunch 构建一个移动网站。

对于用户界面,我想使用 jQuery Mobile。

我开始像这样调整现有的 home_view (Backbone.View):

1
2
3
4
5
6
7
8
9
10
11
12
class exports.HomeView extends Backbone.View
  id: 'home-view'

  render: ->
    console.log"render() homepage"

    $(@el).html require('./templates/home')

    $.mobile.changePage('#homepage', 'slide', false, false)
    console.log $(@el)

    @

这不起作用,我怀疑这是因为 Backbone 在 jQuery Mobile 初始化之前或之后"注入"了 html 或其他什么?

我可以使用 Firebug 和 Chrome 的 Inspect Element 检查标记,但 div 元素设置为 display:none; (所以这似乎再次指向 jQuery Mobile 未初始化或类似的东西)

./templates/home 是一个简单的 'eco' 模板,带有一些基本的 jQuery Mobile 标记,它看起来像这样:(并被注入到 body 标签中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<ul>

           
<li>
Home
</li>

       
<li>
Help
</li>

   
</ul>

    <!-- /navbar -->

   
       
            Home

我在 SA 和 Google 上搜索了解决方案,但没有成功。任何提示将不胜感激。谢谢!


正如对此问题的评论中的某处所述,您可以在渲染页面后执行此操作:

1
$("#pageId").trigger("create");

这将强制 jQuery Mobile 更新您的页面并解决您的问题。


在你的渲染函数中尝试:

1
2
3
4
5
6
7
8
9
render:function(){
var container = this.options.viewContainer;

// your code

container.html($(this.el));
container.trigger('create');
return this;
}

这对我来说很好用;)


根据 Sandor 但我的方法是在 'pagebeforeshow' 期间触发 'create' 事件,如下所示:

1
2
3
4
$('#pageId').bind('pagebeforeshow', function(event) {
   var currentPage = event.currentTarget;
   $(currentPage).trigger('create');
});

这将应用您在重新渲染 DOM 期间丢失的所有样式。


上面的答案,涉及使用 $(currentPage).trigger('create'); 修复了问题,但是因为修复是在之后应用的(在视图页面被 $.mobile.changePage() 呈现和显示之后),用户会得到一个令人不快的副作用:由于 jquery mobile 应用的样式改变,视图闪烁。

我对这个问题的解决方案是在动态渲染完成后从视图中触发自定义事件并将 $.mobile.changePage() 绑定到该事件。这会导致输出被"缓冲"直到完成,然后完全样式化。

这是一个例子:

在我的视图的 initialize 函数中,我有代码等待模型/集合在获取时触发的事件和呈现 html 动态部分的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
window.MyView = Backbone.View.extend({

// some other code here

initialize: function() {
    this.listenTo(this.collection,"fetchCompleted:CollectionName",  this.renderRows);
},

renderRows: function (eventName) {
    $(this.el).find('div[class="content-primary"]').html(this.template_ul({data: this.collection}));
    this.trigger( 'view:ready' );
},
//...

...然后在路由器中我有以下 changePage() 的代码:

1
2
3
myViewObject.on( 'view:ready', function() {
    $.mobile.changePage($(next.el), {changeHash:false, transition: transition});
});