私の問題の簡単な要約: ビューの最初のレンダリングにはコレクション内の要素が含まれていますが、2 番目のレンダリングには含まれていません。詳しくは続きを読む...
また、注意: 次のコードはハッピー パスを表しており、潜在的なエラー処理コードが欠落している可能性がたくさんあることを認識しています。これは簡潔にするために意図的に行われています。
私は backbone.js にかなり慣れていないため、次のシナリオのソリューションを実装する正しい方法を見つけるのに苦労しています。
アプリケーションのメイン レイアウトとなるレンダリングされたコンテンツを格納/表示するために、2 つのメイン リージョンでシェル化されたページがあります。一般に、次のようになります。
-------------------------------------------
| | |
| | |
| Content | Actions |
| Panel | Panel |
| | |
| | |
| | |
| | |
| | |
| | |
-------------------------------------------
私は、データを取得している HTTP API を持っています。これは、実際には、さまざまなモジュールのリソース情報を、OPTIONS
各モジュールのベース URL への呼び出しからの JSON 結果の形式で提供します。たとえば、次のようなOPTIONS
リクエストをhttp://my/api/donor-corps
返します。
[
{
"Id":0,
"Name":"GetDonorCorps",
"Label":"Get Donor Corps",
"HelpText":"Returns a list of Donor Corps",
"HttpMethod":"GET",
"Url":"https://my/api/donor-corps",
"MimeType":"application/json",
"Resources":null
}
]
アプリケーションには、私が呼び出しているバックボーン コレクションがあります。これは、複数の異なるバックボーン ビューによってレンダリングされ、アプリケーションの異なるページに異なる方法で表示される可能性のあるオブジェクトDonorCorpsCollection
の読み取り専用コレクションになります (最終的には...後で.. DonorCorpModel
.現時点ではそうではありません)。のurl
プロパティは、API モジュール リソースを取得するための最初の呼び出しの結果の「GetDonorCorps」プロパティを持つオブジェクトDonorCorpsCollection
のプロパティである必要があります (上記を参照)。Url
Name
OPTIONS
アプリケーションには上部にメニューバーがあり、クリックするとアプリのさまざまなページが表示されるリンクがあります。今のところ、アプリには「ホーム」ページと「プレソート」ページの 2 つのページしかありません。「ホーム」ビューでは、両方のパネルにプレースホルダー情報が含まれているだけで、ユーザーがメニュー バーのリンクをクリックして実行するアクションを選択する必要があることを示しています。DonorCorpsCollection
ユーザーが「並べ替え前」ページのリンクをクリックすると、アクション パネルに順序付けされていないリストとしてレンダリングするバックボーン ビューを表示したいだけです。
私は現在、アプリケーション コードを整理してカプセル化するためにJavaScript モジュール パターンを使用しています。現在、私のモジュールは次のようになっています。
var myModule = (function () {
// Models
var DonorCorpModel = Backbone.Model.extend({ });
// Collections
var DonorCorpsCollection = Backbone.Collection.extend({ model : DonorCorpModel });
// Views
var DonorCorpsListView = Backbone.View.extend({
initialize : function () {
_.bindAll(this, 'render');
this.template = _.template($('#pre-sort-actions-template').html());
this.collection.bind('reset', this.render); // the collection is read-only and should never change, is this even necessary??
},
render : function () {
$(this.el).html(this.template({})); // not even exactly sure why, but this doesn't feel quite right
this.collection.each(function (donorCorp) {
var donorCorpBinView = new DonorCorpBinView({
model : donorCorp,
list : this.collection
});
this.$('.donor-corp-bins').append(donorCorpBinView.render().el);
});
return this;
}
});
var DonorCorpListItemView = Backbone.View.extend({
tagName : 'li',
className : 'donor-corp-bin',
initialize : function () {
_.bindAll(this, 'render');
this.template = _.template($('#pre-sort-actions-donor-corp-bin-view-template').html());
this.collection.bind('reset', this.render);
},
render : function () {
var content = this.template(this.model.toJSON());
$(this.el).html(content);
return this;
}
});
// Routing
var App = Backbone.Router.extend({
routes : {
'' : 'home',
'pre-sort', 'preSort'
},
initialize : function () { },
home : function () {
// ...
},
preSort : function () {
// what should this look like??
// I currently have something like...
if (donorCorps.length < 1) {
donorCorps.url = _.find(donorCorpResources, function (dc) { return dc.Name === "GetDonorCorps"; }).Url;
donorCorps.fetch();
}
$('#action-panel').empty().append(donorCorpsList.render().el);
}
})
// Private members
var donorCorpResources;
var donorCorps = new DonorCorpsCollection();
var donorCorpsList = new DonorCorpsListView({ collection : donorCorps });
// Public operations
return {
Init: function () { return init(); }
};
// Private operations
function init () {
getAppResources();
}
function getAppResources () {
$.ajax({
url: apiUrl + '/donor-corps',
type: 'OPTIONS',
contentType: 'application/json; charset=utf-8',
success: function (results) {
donorCorpResources = results;
}
});
}
}(myModule || {}));
最後に、これはすべて次の HTML を使用しています。
...
<div class="row-fluid">
<div id="viewer" class="span8">
</div>
<div id="action-panel" class="span4">
</div>
</div>
...
<script id="pre-sort-actions-template" type="text/template">
<h2>Donor Corps</h2>
<ul class="donor-corp-bins"></ul>
</script>
<script id="pre-sort-actions-donor-corp-bin-view-template" type="text/template">
<div class="name"><%= Name %></div>
</script>
<script>
$(function () {
myModule.Init();
});
</script>
...
これまでのところ、 「事前並べ替え」メニュー リンクを初めてクリックしたときに、これを機能させることができました。クリックすると、Donor Corps のリストが期待どおりに表示されます。しかし、[ホーム] リンクをクリックしてから、[事前並べ替え] リンクをクリックすると、今度はヘッダーが<ul class="donor-corp-bins"></ul>
表示されますが、リスト項目がなく空です。...そして、なぜ、または何を別の方法で行う必要があるのか わかりません。backbone.js の Views と Routers は一般的に理解しているように感じますが、実際には何かが足りないようです。
一般的に、これはかなり単純なシナリオのように思えます。ここで何か例外的なことをしようとしているような気がしませんが、正しく動作させることができず、その理由を理解できないようです. アシスト、または少なくとも正しい方向へのナッジは、非常に高く評価されます。