2012-10-05 58 views
0

我一直在試圖使用backbonejs和jqm在一起。骨幹視圖傳遞給jQuery Mobile

我可以呈現主頁面正常。該頁面上有一個用戶可以點擊的列表。所選項目應顯示詳細信息頁面,其中包含所選清單項目的信息。詳細信息頁面是一個骨幹視圖,其中包含在項目的視圖對象中呈現的模板。

詳細信息的視圖.render()生成html ok,並將主頁面的div標記的html設置爲呈現項目的細節標記。它看起來像這樣:

podClicked: function (event) {    
     console.log("PodListItemView: got click from:" + event.target.innerHTML + " id:" + (this.model.get("id") ? this.model.get("id") : "no id assigned") + "\n\t CID:" + this.model.cid); 
     var detailView = new PodDetailView({ model: this.model }); 
     detailView.render(); 
    }, 

詳細信息視圖的渲染看起來像這樣:

render: function() { 
     this.$el.html(this.template({ podId: this.model.get("podId"), isAbout_Name: this.model.get("isAbout_Name"), happenedOn: this.model.get("happenedOn") })); 
     var appPageHtml = $(app.el).html($(this.el)); 
     $.mobile.changePage(""); // <-- vague stab in the dark to try to get JQM to do something. I've also tried $.mobile.changePage(appPageHtml). 
     console.log("PodDetailView: render"); 
     return this; 
    } 

我可以看到詳細的觀點得到了檢查Chrome的開發工具HTML編輯器在網頁上呈現,但它不是在頁面上顯示。我看到的只是一個空白頁面。

我試過$ .mobile.changePage(),但沒有一個URL會引發錯誤。

如何讓JQM將它的類標籤應用到呈現的html中?

的HTML和模板看起來像這樣:

<!-- Main Page --> 
<div id="lessa-app" class="meditator-image" data-role="page"></div> 
<!-- The rest are templates processed through underscore --> 
<script id="app-main-template" type="text/template"> 
    <div data-role="header"> 
     <h1>@ViewBag.Title</h1> 
    </div> 
    <!-- /header --> 

    <div id="main-content" data-role="content"> 
     <div id="pod-list" data-theme="a"> 
      <ul data-role="listview" > 
      </ul> 
     </div> 
    </div> 

    <div id="main-footer" data-role='footer'> 
     <div id="newPod" class="ez-icon-plus"></div> 
    </div> 
</script> 
<script id="poditem-template" type="text/template"> 
    <span class="pod-listitem"><%= isAbout_Name %></span> <span class='pod-listitem ui-li-aside'><%= happenedOn %></span> <span class='pod-listitem ui-li-count'>5</span> 
</script> 
<script id="page-pod-detail-template" type="text/template"> 
    <div data-role="header"> 
     <h1>Pod Details</h1> 
    </div> 
    <div data-role="content"> 
     <div id='podDetailForm'> 
      <fieldset data-role="fieldcontain"> 
       <legend>PodDto</legend> 
       <label for="happenedOn">This was on:</label> 
       <input type="date" name="name" id="happenedOn" value="<%= happenedOn %>" /> 
      </fieldset> 
     </div> 
     <button id="backToList" data-inline="false">Back to list</button> 
    </div> 
    <div data-role='footer'></div> 
</script> 

預先感謝任何建議......這是甚至是可行的?

回答

0

我終於找到了一種方法來做到這一點。我原來的代碼對這個過程的成功有幾個障礙。

做的第一件事是攔截jquerymobile的(v.1.2.0)changePage事件是這樣的: (我已經改編自JQM的文檔大綱,並在有用的意見左:看http://jquerymobile.com/demos/1.2.0/docs/pages/page-dynamic.html

$(document).bind("pagebeforechange", function (e, data) { 

     // We only want to handle changePage() calls where the caller is 
     // asking us to load a page by URL. 
     if (typeof data.toPage === "string") { 

      // We are being asked to load a page by URL, but we only 
      // want to handle URLs that request the data for a specific 
      // category. 
      var u = $.mobile.path.parseUrl(data.toPage), 
       re = /^#/; 

      // don't intercept urls to the main page allow them to be managed by JQM 
      if (u.hash != "#lessa-app" && u.hash.search(re) !== -1) { 

       // We're being asked to display the items for a specific category. 
       // Call our internal method that builds the content for the category 
       // on the fly based on our in-memory category data structure. 
       showItemDetail(u, data.options); // <--- handle backbone view.render calls in this function 

       // Make sure to tell changePage() we've handled this call so it doesn't 
       // have to do anything. 
       e.preventDefault(); 
      } 
     } 
    }); 

的changePage()調用,其中傳遞給podClicked方法項的列表骨幹視圖事件聲明製備如下:

 var PodListItemView = Backbone.View.extend({ 
     tagName: 'li', // name of (orphan) root tag in this.el 
     attributes: { 'class': 'pod-listitem' }, 

     // Caches the templates for the view 
     listTemplate: _.template($('#poditem-template').html()), 
     events: { 
      "click .pod-listitem": "podClicked" 
     }, 
     initialize: function() { 
      this.model.bind('change', this.render, this); 
      this.model.bind('destroy', this.remove, this); 
     }, 
     render: function() { 
      this.$el.html(this.listTemplate({ podId: this.model.get("podId"), isAbout_Name: this.model.get("isAbout_Name"), happenedOn: this.model.get("happenedOn") })); 
      return this; 
     }, 
     podClicked: function (event) { 
      $.mobile.changePage("#pod-detail-page?CID='" + this.model.cid + "'"); 
     }, 
     clear: function() { 
      this.model.clear(); 
     } 
    }); 

在「showItemDetail」函數的查詢端口對該項目的主幹模型的CID解析URL的離子。我再次修改了上面顯示的jquerymobile.com鏈接中提供的代碼。

問題:我仍然在計算將showItemDetail()中的代碼放在視圖的render()方法內是否更好。具有定義的功能似乎會減損骨幹的架構模型。另一方面,讓render()函數知道調用JQM changePage似乎違反了「分離關注點」的原則。任何人都可以提供一些見解和指導?

// the passed url looks like #pod-detail-page?CID='c2' 
    function showItemDetail(urlObj, options) { 

     // Get the object that represents the item selected from the url 
     var pageSelector = urlObj.hash.replace(/\?.*$/, ""); 
     var podCid = urlObj.hash.replace(/^.*\?CID=/, "").replace(/'/g, ""); 

     var $page = $(pageSelector), 
      // Get the header for the page. 
      $header = $page.children(":jqmData(role=header)"), 
      // Get the content area element for the page. 
      $content = $page.children(":jqmData(role=content)"); 

     // The markup we are going to inject into the content area of the page. 
     // retrieve the selected pod from the podList by Cid 
     var selectedPod = podList.getByCid(podCid); 

     // Find the h1 element in our header and inject the name of the item into it 
     var headerText = selectedPod.get("isAbout_Name"); 
     $header.html("h1").html(headerText); 

     // Inject the item info into the content element 
     var view = new PodDetailView({ model: selectedPod }); 
     var viewElHtml = view.render().$el.html(); 
     $content.html(viewElHtml); 

     $page.page(); 

     // Enhance the listview we just injected. 
     var fieldContain = $content.find(":jqmData(role=listview)"); 
     fieldContain.listview(); 

     // We don't want the data-url of the page we just modified 
     // to be the url that shows up in the browser's location field, 
     // so set the dataUrl option to the URL for the category 
     // we just loaded. 
     options.dataUrl = urlObj.href; 

     // Now call changePage() and tell it to switch to 
     // the page we just modified. 
     $.mobile.changePage($page, options); 
    } 

所以上面提供了事件管道。

我遇到的另一個問題是頁面設置不正確。最好將頁面框架放在主html中,而不要放在下一個要呈現的下劃線模板中。我認爲,避免jqm接管時html不存在的問題。

<!-- Main Page --> 
<div id="lessa-app" data-role="page"> 
    <div data-role="header"> 
    <h1></h1> 
    </div> 
    <!-- /header --> 
    <div id="main-content" data-role="content"> 
    <div id="pod-list" data-theme="a"> 
     <ul data-role="listview"> 
     </ul> 
    </div> 
    </div> 
    <div id="main-footer" data-role='footer'> 
    <div id="main-newPod" class="ez-icon-plus"></div> 
    </div> 
</div> 
<!-- detail page --> 
<div id="pod-detail-page" data-role="page"> 
    <div data-role="header"> 
     <h1></h1> 
    </div> 
    <div id="detail-content" data-role="content"> 
     <div id="pod-detail" data-theme="a"> 
     </div> 
    </div> 
    <div id="detail-footer" data-role='footer'> 
    <a href="#lessa-app" data-role="button" data-mini="true">back</a> 
    </div> 
</div>