javascript - Backbone : remove ellipsis onclick

标签 javascript jquery backbone.js underscore.js ellipsis

一些背景

我正在尝试创建一个类似 Twitter 的提要,其中推文/行将在点击时展开,从而显示更多信息。

数据是从 JSON 文件中提取的(从后端发送到前端)。 我使用主干在前端渲染数据。

假设我的提要显示 10 行,每行显示一些信息,然后单击行/div 展开以显示更多信息。 描述字段包含大量文本,因此我在其上应用了 JavaScript 省略号。我使用 Javascript 省略号,因为简短描述需要超过一行(不认为 CSS 省略号适用于超过一行)。

  1. 我创建了一个插件,它将 chop 描述文本,并且在单击时我想删除省略号并将其替换为完整描述(因为行将展开)。

  2. 我创建了一个插件,它将完整的描述(在被 chop 之前)保存到一个数组中。

问题

我的想法是将单击的行的索引(currentTarget)与保存的行的索引(在数组中)进行比较,然后用完整的描述替换省略号文本,然后使用 jQuery animate 展开 div。

我不确定是否有办法从主干“点击事件”获取索引(以便将其与数组中保存的索引进行比较)?

如果有更好的方法来解决这个问题,请随时告诉我。

提前致谢

这是我的代码:

chop 并保存原始文本函数

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

Backbone 模型和集合

/**
 * Model
 */
var Task = Backbone.Model.extend();

/**
 * Collections
 */
var RecentTasksList = Backbone.Collection.extend({
    model: Task,
    url: 'json/recentTasks.json'
});

主干 View

/**
 * 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。 我为包含单击事件的选项卡创建了一个 View 。我是否需要每次都实例化模型并查看和获取数据,或者我可以重用已经初始化的模型吗?

我为第二个选项卡创建了一个新 View 。从服务器获取 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;
    }
});

然后我创建了一个选项卡 View ,它将在单击时显示正确的任务。

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

最佳答案

我认为您应该为单个任务创建一个新 View 。然后在该 View 中,您可以处理点击,这样您就可以访问任务模型,并且还可以非常轻松地访问该 View 的 DOM。

然后你就可以摆脱 FullTask​​View 和 jQuery 插件了。

 /**
 * Model
 */
var Task = Backbone.Model.extend({
    getShortDescription: function(){
       var desc = this.get('description');
       if(desc.length > 165){
        return desc.trim().substring(0, 165).split(" ").slice(0, -1).join(" ") + "…";
       }
       return desc;
    }
});

添加新的TaskView,并更改RecentTasksView来创建/渲染它们。

/**
 * Views
 */

var TaskView = Backbone.View.extend({
    template: _.template($('#recentTasksTemplate').html()),
    events: {
       'click': 'showFullDetails'
    },
    render: function(){
        // pass the model json, plus the short description to the template
        this.$el.html(this.template({
            data: this.model.toJSON(), 
            shortDesc: this.model.getShortDescription()
            }));

        return this;
    },
    showFullDetails: function(){
       // change text, show/hide, animate here
       // In the view, this.$() will only match elements within this view.

       // if expand...
       this.$('.description').html(this.model.get('description'));

       // if hide...
       this.$('.description').html(this.model.getShortDescription());
    }
});
var RecentTasksView = Backbone.View.extend({
    el: '.taskList',
    render: function(){
        _.each(this.model.models, function(model){
            // create a view for each task, render and append it
            var taskView = new TaskView({model: model});
            this.$el.append(taskView.render().el);
        }, this);

        return this;
    }
});

更改模板以使用传递给它的新数据。

// access the model stuff with data.title, etc. 
<script id="recentTasksTemplate" type="text/template">
    <div class="task clearfix">
        <div class="image">
            <img src="<%= data.image %>" />
        </div>
        <div class="details">
            <h3 class="title"><%= data.title %></h3>
            <div class="description">
                <%= shortDesc %>
            </div>
        </div>
    <div>
</script>

编辑:

Backbone View 旨在管理 DOM 元素,因此让每个任务成为其自己的 View 实例是一个好主意。这使得根据点击扩展和更改文本变得更容易。此外,最佳实践是不要让 View 外部的代码更改其 DOM 元素内的内容,因此最好在每个任务 View 内进行该操作。

这类似于 Todo 示例中的 TodoView:

http://backbonejs.org/docs/todos.html

http://backbonejs.org/examples/todos/index.html

您可以向模板函数传递任何 javascript 对象(甚至是具有函数的对象,而不仅仅是属性)。由于您想要显示一些技术上不属于模型一部分的数据,因此传递 data 对象只是将您需要的内容放入模板中的一种方法。

关于javascript - Backbone : remove ellipsis onclick,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14948215/

相关文章:

javascript - 如何编写服务器端 node.js/express 方法?

javascript - 如何验证动态添加的相关日历字段

jquery - Kendo React UI DataTable Filter 与 JQuery Kendo UI 具有相同的行为

javascript - collection.fetch() 中显式上下文丢失

javascript - 如何使用 HtmlWebpackPlugin 在正文代码之前注入(inject)包源代码?

javascript - 如何在我的 IOS 应用程序中包含我的 html 页面的 js 文件?

javascript - onsubmit 不执行 JavaScript 函数

javascript - 悬停悬停文本框在选中时保持固定

backbone.js - 如何在主干文章中添加调整大小事件?

javascript - "Cannot call method ' 关于 ' of undefined"问题