【问题标题】:Selected Dropdown ids in Knockout JSKnockout JS 中的选定下拉列表 ID
【发布时间】:2017-03-30 13:53:43
【问题描述】:

我有一个数组doorsForSite,其中每个项目will have a Doors Array and each door will have a Schedules array

看起来像:

            var scheduleList = new[] 
            {
                new { ScheduleId = "Schedule1",ScheduleName = "Always On" },
                new { ScheduleId = "Schedule2",ScheduleName = "Never On"}
            };

            var doorsForSite = new[]
                {
                new { ControllerId ="controller1",ControllerName="Eagle",IsChecked = "false",
                        Doors = new[]
                        {
                            new { DoorId="Door1",DoorName="DoorOne",Schedules = scheduleList},
                            new { DoorId = "Door2", DoorName = "DoorTwo",Schedules = scheduleList}
                        }

                    },
                new { ControllerId ="controller2",ControllerName="NetAxis",IsChecked = "false",
                        Doors = new[]
                        {
                            new { DoorId=  "Door3",DoorName="DoorThree",Schedules = scheduleList},
                            new { DoorId = "Door4", DoorName = "DoorFour",Schedules = scheduleList},
                            new { DoorId = "Door5", DoorName = "DoorFive",Schedules = scheduleList}
                        }

                    }
            };

现在在 UI 中..

<ul class="accgrouptableaccordian scroll-x scroll-y">
    <!-- ko foreach: $data.AddModel.ControllerDoors -->
    <li>
        <div class="panel-group">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h4 class="panel-title">
                        <span>
                            <span>
                                <span class="ispicon ispicon_accordian_droparrow">
                                </span>
                                <span class="title" style="line-height:20px;" data-bind="text: ControllerName() + ' - ' + Doors().length + ' Doors'">
                                </span>
                            </span>
                            <span>

                            </span>
                        </span>
                    </h4>
                </div>
                <div class="panel-collapse">
                    <div class="panel-body">
                        <div class="table-responsive panel-body">
                            <table class="table">
                                <tbody data-bind="foreach:Doors">
                                    <tr>
                                        <td>
                                            <div>
                                                <span data-bind="text:DoorId"></span>
                                            </div>
                                        </td>
                                        <td class="col-md-4">

                                            <select name="drpSchedulesAccess" class="form-control drpSchedulesAccess" data-bind="options:$data.Schedules,
                                                optionsText: 'ScheduleName',
                                                optionsValue: 'ScheduleId',
                                                value: $data.ScheduleId"></select>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </li>
    <!-- /ko -->
</ul>

但在 Viewmodel 中,我只想在下拉列表中获取 选中的门的选定计划的值。

但这并没有发生。

我做到了

            ko.utils.arrayForEach(this.AddModel.ControllerDoors(), function (item) {
                ko.utils.arrayForEach(item.Doors(), function (item) {
                    doorsSelected.push(item);
                });

            });
            var doors = ko.utils.arrayFilter(doorsSelected, function (item) {
                return item.IsChecked == true;
            });

            var doorIds = ko.utils.arrayMap(doors, function (door) {
                if (jQuery.inArray(door.DoorId, doorIds) == -1) {
                    return door.DoorId;
                }
            });

            ko.utils.arrayForEach(doors, function (item) {
                debugger;
                ko.utils.arrayForEach(item.Schedules, function (item) {

                    $('.drpSchedulesAccess option:selected').each(function (i) {
                        schedulesSelected.push($(this).val());
                    });
                });

            });

我从下拉列表中检查了 3 个门和 3 个选定的时间表。

但我得到的计划数组长度为 30。

为什么会这样?

【问题讨论】:

    标签: javascript jquery arrays knockout.js


    【解决方案1】:

    你可能需要稍微修改你的代码,最重要的是做任何事情都是 knockout-ish 方式。

    视图模型:

    var ViewModel = function() {
      var self = this;
      self.ControllerDoors = ko.observableArray(ko.mapping.fromJS(doorsForSite)()); // mapping to convert everything to observable
      self.check = function() {
        var doorsSelected = [];
        ko.utils.arrayForEach(self.ControllerDoors(), function(item) {
          //you can add condition here based on controllerName IsChecked & reduce looping
          ko.utils.arrayForEach(item.Doors(), function(item) {
            if (item.IsChecked())
              doorsSelected.push(item);
          });
        });
        console.log(doorsSelected);
      }
    };
    

    查看工作演示 here 并检查 控制台窗口 以查找结果。

    注意事项:

    () : 用于读取 observable (你可以在当前视图中找到它的用法)

    【讨论】:

      【解决方案2】:

      您在视图中查找所选选项的方式不是“淘汰方式”。在这些行中:

      $('.drpSchedulesAccess option:selected').each(function (i) {
        schedulesSelected.push($(this).val());
      });
      

      您正在使用 DOM 来存储您的 ViewModel 状态,这本身还不错,但不是淘汰赛的工作原理。

      使用敲除时,您的 ViewModel 应包含所有数据并通过数据绑定与 DOM 通信。

      您还没有向我们展示工作代码的 sn-p,因此我将尝试重新创建部分 UI 以展示它应该如何工作。

      var DoorViewModel = function(schedules, door) {
          return Object.assign({
            checked: ko.observable(true),
            selectedSchedule: ko.observable(),
            schedules: schedules
          }, door);
      };
      
      var ViewModel = function(doors, schedules) {
         this.doors = ko.observableArray(doors.map(DoorViewModel.bind(null, schedules)));
        
         this.selectedScheduleIds = ko.computed(function() {
             return this.doors()
               .filter(function(door) { return door.checked(); })
               .map(function(door) {
                 return door.selectedSchedule() 
                   ? door.selectedSchedule().ScheduleId
                   : null;
               });
         }, this);
      };
      
      var schedules = [{
        'ScheduleId': "Schedule1",
        'ScheduleName': "Always On"
      }, {
        'ScheduleId': "Schedule2",
        'ScheduleName': "Never On"
      }];
      
      var doors = [{
        'DoorId': "Door1",
        'DoorName': "DoorOne"
        }, {
        'DoorId': "Door2",
        'DoorName': "DoorTwo"
      }];
      
      ko.applyBindings(new ViewModel(doors, schedules));
      <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
      
      <ul data-bind="foreach: doors">
        
        <li>
          <input type="checkbox" data-bind="checked: checked">
          <span data-bind="text: DoorName"></span>
          
          <select data-bind="options: schedules, 
                             value: selectedSchedule,
                             optionsText: 'ScheduleName'"></select>
                             
          
        </li>
      </ul>
      
      <pre data-bind="text: JSON.stringify(selectedScheduleIds(), null, 2)"></pre>

      【讨论】:

        猜你喜欢
        • 2014-06-06
        • 1970-01-01
        • 2018-08-30
        • 2012-02-14
        • 2014-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-03
        相关资源
        最近更新 更多