2016-11-16 2 views
0

У меня есть массив doorsForSite, где каждый элемент will have a Doors Array and each door will have a Schedules array.Выбранные выпадающие идентификаторы в нокаут JS

Это выглядит следующим образом:

  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} 
         } 

        } 
      }; 

Сейчас в пользовательском интерфейсе ..

<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.

Почему это так?

enter image description here

ответ

0

, как ты смотришь на выбранные опции на ваш взгляд, не является «Нокаут путь». В этих строках:

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

вы используете DOM для хранения состояния ViewModel, что не плохо само по себе, но не так, как работает нокаута.

При использовании нокаута ваша ViewModel должна содержать все данные и связываться с DOM посредством привязки данных.

Вы не показали нам фрагмента рабочего кода, поэтому я попытаюсь воссоздать части вашего пользовательского интерфейса, чтобы показать, как он должен работы.

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>

1

вам, возможно, потребуется немного Твик код & самое главное сделать Everthing это нокаут-иш путь.

ViewModel:

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 и проверить окно консоли найти результаты.

Things отметить:

(): используется для чтения наблюдаемым (вы можете найти его использование в текущем виде)

Смежные вопросы