将有序结果组织成标记的部分

时间:2013-09-09 19:31:34

标签: c# jquery asp.net-mvc knockout.js

我正在尝试将返回的结果正确放入标记的部分 - 我的意思的例子。

控制器:

public IEnumerable<Users> GetUserList(int? id, int? pageNumber)
        {
            if (!id.HasValue)
                throw new HttpResponseException(HttpStatusCode.NotFound);

            int _pageNum = pageNumber.HasValue ? pageNumber.Value : 1;
            return new UserService().GetUsers(id.Value, pageNumber: _pageNum);
        }

查看:

<div id="listView"  data-bind="template: { name: 'list', foreach: Users }">
            <section id="Images">
                <section id="users"></section>
            </section>
        </div>

knockout.js / jquery:更新

  var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// The ViewModel for the page
var viewModel = {
    Users: ko.observableArray([]),
    users: ko.observableArray([]),
    groups: ko.computed({
        read: function(){
            var groups = [];
            var groupLetter;
            for(var i = 0; i <letters.length; i++){
                viewModel.Users.groups[letters[i]].users([]);
            }
            ko.utils.arrayForEach(viewModel.users(), function (user) {
                groupLetter = user.name()[0].toUpperCase();
                if (groups.indexOf(groupLetter) < 0) {
                    groups.push(groupLetter);
                }
                groups[groupLetter].users.push(user);
            });
            return groups.sort();
        },
        deferEvaluation: true
    }),

};
for (var i = 0; i < letters.length; i++) {
    viewModel.users.groups[letters[i]] = { users: ko.observableArray([]) };
}

//页面的ViewModel

var viewModel = {
    Users: ko.observableArray([]), //already a sorted list of users
    TotalRoster: null,
    CurrentPage: ko.observable(1),
    DataIsLoading: ko.observable(false),

};

所以这会在视图中返回: 阿曼达
鲍勃
坦率 凯特 添

我希望在视图中显示:

A(标题)

阿曼达

B(标题)

鲍勃

F(标题)

弗兰克

K(标题)

凯特

T(标题)

蒂姆

主要用于观看者的视觉参考 - 它将显示存在的用户的字母标题,因此如果没有名称以S开头的用户则不会有S标题。关于我可以调查的地方或者可以称之为什么的任何帮助我都可以读到这将是很好的。

2 个答案:

答案 0 :(得分:0)

您可以按客户端的名称对用户进行分组,如下所示:

// assuming the array is sorted
var users = ['Amanda', 'Anna', 'Bob', 'Frank', 'Francois', 'Sam'];

var lastGroup = null;
var vm = {
    groups: []
};

ko.utils.arrayForEach(users, function (user) {
    // known group
    if (lastGroup && lastGroup.name == user[0]) {
        lastGroup.users.push(user);
    } else {            
        // unknown group
        lastGroup = {
            name :user[0], users : [user]
        };
        vm.groups.push(lastGroup);
    }
});



<div data-bind="foreach:groups">
    <span data-bind="text:name" style="font-weight: bold"></span>    
    <br/>
    <div data-bind="foreach:users">
        <span data-bind="text:$data"></span>
        <br/>
    </div>
</div>

See fiddle

答案 1 :(得分:0)

我可以告诉你,通过循环绑定中的Users数组,你无法做到这一点。每次迭代都将生成为每个User对象提供的模板化html代码。

我要考虑的一种方法是创建一个基于用户名的第一个字母的动态数组,并将这些组附加到根observableArray对象。

function ViewModel() {
    var self = this;
    var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    self.users = ko.observableArray([]);
    self.users.groups = ko.computed({
        read: function(){
            var groups = [];
            var groupLetter;
            for (var i = 0; i < letters.length; i++) {
                self.users.groups[letters[i]].users([]);
            }
            ko.utils.arrayForEach(self.users(), function (user) {
                groupLetter = user.name()[0].toUpperCase();
                if (groups.indexOf(groupLetter) < 0) {
                    groups.push(groupLetter);// not listed?  Add it
                }
                self.users.groups[groupLetter].users.push(user);// Add to the grouped users array
            });
            return groups.sort();
        },
        deferEvaluation: true
    });

    for (var i = 0; i < letters.length; i++) {
        self.users.groups[letters[i]] = { users: ko.observableArray([]) };
    }
}

现在在您的视图中:

<div data-bind="foreach: { data: $root.users.groups, as: '$group' }">
    <h3 data-bind="text: $group"></h3>
    <ul data-bind="foreach: { data: $root.users.groups[$group].users, as: '$user' }">
        <li data-bind="text: $user.name"></li>
    </ul>
</div>

jsFiddle

*注意:如果您需要在客户端动态更新这些名称,则只需要使用此路由。如果这个清单保持不变,那么最好选择Damien的答案。