少し背景
ツイート/行がクリック時に展開され、より多くの情報が表示されるフィードのようなTwitterを作成しようとしています。
データはJSONファイルから取得されます(バックエンドからフロントエンドに送信されます)。バックボーンを使用して、フロントエンドでデータをレンダリングします。
フィードに10行が表示され、各行にいくつかの情報が表示されたら、行をクリックすると/ divが展開され、より多くの情報が表示されます。説明フィールドにはかなりの量のテキストが含まれているため、JavaScriptの省略記号を適用しています。短い説明は複数行である必要があるため、Javascript省略記号を使用します(CSS省略記号は複数行で機能するとは思わないでください)。
説明テキストを切り捨てるプラグインを作成し、クリックすると省略記号を削除して完全な説明に置き換えます(行が展開されるため)。
(切り捨てられる前に)完全な説明を配列に保存するプラグインを作成しました。
問題
私のアイデアは、クリックされた行のインデックス(currentTarget)を(配列に)保存された行のインデックスと比較し、省略記号のテキストを完全な説明に置き換えてから、divをjQueryanimateで展開することでした。
バックボーンの「クリックイベント」からインデックスを取得する方法があるかどうかわかりません(配列に保存されているインデックスと比較するため)?
これにアプローチするより良い方法があるかどうか私に知らせてください。
前もって感謝します
これが私のコードです:
元のテキスト関数を切り捨てて保存する
/**
* Plugins
*/
var arr = [];
$.fn.truncate = function(){
return this.each(function(index,element){
var elementText = $(element).text();
if(elementText.length > 165){
var truncated = elementText.trim().substring(0, 165).split(" ").slice(0, -1).join(" ") + "…";
}
$(element).text(truncated);
});
};
$.fn.getText = function(){
return this.each(function(index,element){
arr.push({
i: index,
v: $(element).text()
});
});
};
バックボーンモデルとコレクション
/**
* Model
*/
var Task = Backbone.Model.extend();
/**
* Collections
*/
var RecentTasksList = Backbone.Collection.extend({
model: Task,
url: 'json/recentTasks.json'
});
バックボーンビュー
/**
* Views
*/
var RecentTasksView = Backbone.View.extend({
el: '.taskList',
template: _.template($('#recentTasksTemplate').html()),
render: function(){
_.each(this.model.models, function(data){
this.$el.append(this.template(data.toJSON()));
}, this);
$('.description').getText();
$('.description').truncate();
return this;
}
});
var FullTaskView = Backbone.View.extend({
el: '.taskContainer',
events: {
'click .task': 'showFullDetails'
},
showFullDetails: function(e){
var eTarget = $(e.currentTarget);
var $desc = $('.description');
if(eTarget.hasClass('expanded')){
eTarget.animate({
'height': '80px'
},
function(){
eTarget.removeClass('expanded');
});
}
else{
console.log($(eTarget).find($desc).html());
eTarget.animate({
//doesn't work lesser IE 8
'height': eTarget[0].scrollHeight
},
function(){
eTarget.addClass('expanded');
});
}
}
});
var AppView = Backbone.View.extend({
el: 'body',
initialize: function(){
//Recent Tasks
var recentTasksList = new RecentTasksList();
var recentTasksView = new RecentTasksView({
model: recentTasksList
});
recentTasksList.bind('reset', function(){
recentTasksView.render();
});
recentTasksList.fetch();
//Full Task Details
var fullTaskView = new FullTaskView();
}
});
var appView = new AppView();
アンダースコアテンプレート
<script id="recentTasksTemplate" type="text/template">
<div class="task clearfix">
<div class="image">
<img src="<%= image %>" />
</div>
<div class="details">
<h3 class="title"><%= title %></h3>
<div class="description">
<%= description %>
</div>
</div>
<div>
</script>
HTML
<div class="taskContainer">
<div class="taskList"></div>
</div>
編集
最後の質問です。ページにタブを追加しました(同様の召喚状)。同じ種類の情報がクリック時に表示されます(同じテンプレートを使用しています)。たとえば、RecentTaskとPopularTaskがあります。クリックイベントを含むタブのビューを作成しました。毎回モデルをインスタンス化してデータを表示およびフェッチする必要がありますか、それともすでに初期化されているデータを再利用できますか?
2番目のタブの新しいビューを作成しました。サーバーからJSONファイルを取得する:
var PopularTasksList = Backbone.Collection.extend({
model: Task,
url: 'json/popularTasks.json'
});
var PopularTasksView = Backbone.View.extend({
el: '.taskList',
render: function(){
$('.taskList').empty();
_.each(this.model.models, function(model){
var taskView = new TaskView({model: model});
this.$el.append(taskView.render().el);
}, this);
return this;
}
});
次に、クリック時に正しいタスクを表示するタブビューを作成しました。
var TabsView = Backbone.View.extend({
el: 'body',
events:{
'click .tabRecent': 'fetchDataRecentTasks',
'click .tabPopular': 'fetchDataPopularTasks'
},
fetchDataRecentTasks: function(){
var recentTasksList = new RecentTasksList();
var recentTasksView = new RecentTasksView({
model: recentTasksList
});
recentTasksList.bind('reset', function(){
recentTasksView.render();
});
recentTasksList.fetch();
},
fetchDataPopularTasks: function(){
var popularTasksList = new PopularTasksList();
var popularTasksView = new PopularTasksView({
model: popularTasksList
});
popularTasksList.bind('reset', function(){
popularTasksView.render();
});
popularTasksList.fetch();
}
});