2012-10-05 3 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; 
    } 

나는 세부 사항의 뷰가 크롬의 dev에 도구 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 이벤트를 차단하는 것입니다

(I은 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'기능 쿼리 포트에서 URL의 항목은 항목의 백본 모델의 CID에 대해 구문 분석됩니다. 다시 위의 jquerymobile.com 링크에 제공된 코드를 수정했습니다.

Qestion : 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> 
관련 문제