0

私はbackbonejsとjqmを一緒に使用しようとしています。

メインページを大丈夫にレンダリングできます。このページには、ユーザーがタップできるリストがあります。選択したアイテムには、選択したリストアイテムに関する情報が記載された詳細ページが表示されます。詳細ページは、アイテムのビューオブジェクトにレンダリングされるテンプレートを備えたバックボーンビューです。

詳細のビュー.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>

アドバイスを事前に感謝します...これも実行可能ですか?

4

1 に答える 1

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」関数では、url のクエリ部分が解析され、アイテムのバックボーン モデルの CID が取得されます。ここでも、上記の jquerymobile.com のリンクで提供されているコードを修正しました。

Qestion: showItemDetail() のコードをビューの render() メソッド内に配置した方がよいかどうか、まだ考え中です。機能を定義すると、バックボーンのアーキテクチャ モデルが損なわれるようです。一方、JQM changePage の呼び出しを render() 関数に認識させることは、「関心の分離」の原則に違反しているようです。誰でも洞察とガイダンスを提供できますか?

    // 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);
    }

したがって、上記はイベント配管を提供します。

私が抱えていたもう 1 つの問題は、ページが正しく設定されていなかったことです。ページ フレームワークをメインの 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>
于 2012-10-09T12:25:08.773 に答える