【问题标题】:nested for loop in javascript knockoutjavascript淘汰赛中的嵌套for循环
【发布时间】:2013-10-07 02:28:12
【问题描述】:

我有两个可观察的数组:

var viewModel = {
    PositionTypes: ko.observableArray([]),
    Users: ko.observableArray([])
}

位置视图模型

var positionViewModel = function (data) {
        var _self = this;
        _self.PositionName = ko.observable(data.PositionName);
        _self.PositionRank = ko.observable(data.PositionRank);
        _self.ContentRole = ko.observable(data.ContentRole);
    }

    positionViewModel.AddPositions = function (data) {
        $.each(data, function (index, value) {
            positionViewModel.PushPosition(value);
        });
    };

    positionViewModel.PushPosition = function (postion) {
        viewModel.PositionTypes.push(new positionViewModel(position));
    };

用户视图模型

    // the ViewModel for a single User
    var userViewModel = function (data) {
        var _self = this;
        _self.ID = ko.observable(data.ID);
        _self.Name = ko.observable(data.Name);
        _self.Email = ko.observable(data.Email);
        _self.ContentRole = ko.observable(data.ContentRole);
    };

    userViewModel.AddUsers = function (data) {
        $.each(data, function (index, value) {
            userViewModel.PushUser(value);
        });
    };


    userViewModel.PushUser = function (user) {
        viewModel.Users.push(new userViewModel(user));
    };

我如何使用 linq.js 以便循环遍历每个位置,以便获得每个位置的所有用户?

foreach( each position in positions)
{
    foreach(each user in users)
    { list of users for the position}
}

【问题讨论】:

  • 用户和职位之间的联系是什么?

标签: javascript knockout.js knockout-2.0 linq.js


【解决方案1】:

您也可以使用ko.utils.arrayForEach,如下所示:

ko.utils.arrayForEach(viewModel.PositionTypes(), function(position){    
     var usersInPosition = ko.utils.arrayFilter(viewModel.Users(), function(user){
          return user.ContentRole() == position.ContentRole();
     });
     ko.utils.arrayForEach(usersInPosition, function(user){        

    });
});

See doc

希望对你有帮助。

【讨论】:

  • 谢谢,我会试试的。这种结构是否会影响整体性能?
  • 否,但如果客户端的 ID 或 Name 属性没有更改,您可以用常规属性“替换”这些 observables。
  • 这里不用arrayForEach(),我觉得改用arrayMap()会更合适。
  • 如果我想使用 linq 怎么办:linq.From(viewModel.PositionTypes) .... 我想使用 linq.js 并传入一个字符串
【解决方案2】:

使用 linq.js,您可以对要比较的列执行连接。

假设您在ContentRoles 之间加入:

var query = Enumerable.From(viewModel.PositionTypes())
    .GroupJoin(viewModel.Users(),
        "$.ContentRole()",  // position selector
        "$.ContentRole()",  // user selector
        "{ Position: $, Users: $$.ToArray() }")
    .ToArray();

所以我认为您想创建一个包含所有职位和用户名映射的对象。您可以使用Aggregate() 函数创建这样一个对象,将所有结果收集到一个对象中。

var userPositions = Enumerable.From(this.PositionTypes())
    .GroupJoin(this.Users(),
        "$.ContentRole()",  // position selector
        "$.ContentRole()",  // user selector
        "{ Position: $, Users: $$ }") // group all users per position
    .Aggregate(
        {}, // start with an empty object
        function (userPositions, x) {
            var positionName = x.Position.PositionName(),
                userNames = x.Users.Select("$.Name()").ToArray();

            // add the new property
            userPositions[positionName] = userNames;
            return userPositions;
        }
    );

【讨论】:

  • 在我看来,我会在查询上绑定数据以显示信息?
  • 你当然可以这样做。尽管您没有向我们展示您的观点或您打算如何使用结果,所以我只是给出了一个通用示例,说明您可以在查询中做什么。此查询按位置对所有用户进行分组。
  • 我想使用 linq.js 并传入一个字符串,以便外部循环是位置,然后为每个位置选择用户,并将每个用户与其位置分组
  • 对不起,我不明白你在说什么。如果您说要按某个位置对所有用户进行分组,那么上面显示的查询应该可以为您完成。如果您很难描述自己在说什么,那么如果您提供一些输入数据的示例和您预期的输出数据的示例,将会有所帮助。
  • 所以我有一个职位列表:(老板、主管、工人),我有一个用户列表(亚当、马特、蒂姆、汤姆、约翰)。我想在javascript中写一个类似linq的查询:linq.From(viewModel.PositionTypes).ForEach(users in viewModel.Users.where(x=>x.ContentRole == viewModel.PositionTypes.ContentRole) //return info,结果将是:Boss: John; Supervisor: matt, tim; Workers: adam, tim
猜你喜欢
  • 1970-01-01
  • 2019-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
  • 2017-08-12
  • 2014-12-11
  • 2011-08-11
相关资源
最近更新 更多