2016-02-22 3 views
1

У меня есть массив объектов с наблюдаемым свойством, связанным с группой переключателей. Наблюдаемое свойство может иметь только следующие значения ['Primary', 'Secondary', 'Occasional', 'none']Как сделать один элемент в наблюдаемом массиве изменить другой элемент в этом массиве

Вот HTML.

<!--ko foreach: allDriversForPolicy--> 
<div class="col-md-2"> 
    <a href="#" class="thumbnail"> 
     <div class=""> 
      <label><input type="radio" value="Primary" data-bind="checked: vehicleDriverType, attr: {name: id}"/>Primary</label> 
      <label><input type="radio" value="Secondary" data-bind="checked: vehicleDriverType, attr: {name: id}" />Secondary</label> 
      <label><input type="radio" value="Ocasional" data-bind="checked: vehicleDriverType, attr: {name: id}" />Ocasional</label> 
      <label><input type="radio" value="" data-bind="checked: vehicleDriverType, attr: {name: id}" />None</label> 
     </div> 
    </a> 
</div> 
<!--/ko--> 

И вот JavaScript, чтобы запустить его.

var SimpleListModel = function() { 
    this.allDriversForPolicy = ko.observableArray([ 
    {'id': 'abe', 'vehicleDriverType': 'Primary'}, 
    {'id': 'bob', 'vehicleDriverType': 'Secondary'}, 
    {'id': 'charlie', 'vehicleDriverType': ''} 
    ]); 
}; 

ko.applyBindings(new SimpleListModel()); 

jsfiddle is here. Морщинка, с которой я сталкиваюсь, является дополнительным требованием, что из всех объектов может быть только один первичный, поэтому мне бы хотелось, чтобы поведение было, если Primary выбрано, а затем пройти через массив и переключить любые объекты с помощью свойства наблюдаемого установите «Первичный» на «Вторичный».

Как это сделать?

+1

Пожалуйста, удалите любой код * не *, имеющий отношение к вопросу, и * добавьте * достаточно кода для воспроизведения вашего сценария. – Jeroen

+0

Хорошо, я обрезал его. Это воспроизведет основы того, что у меня есть сейчас. – Maleki

+0

Не могли бы вы добавить JS, необходимый для создания полного воспроизведения? Например, см. [Этот последний ответ, который я опубликовал] (http://stackoverflow.com/a/35547107/419956), для руководства см. [Mcve]. – Jeroen

ответ

1

Примечание: у вас довольно странный бит разметки с тегом a, обертывающим весь другой код. Я удалил этот бит в моем примере ниже.

Требование, которое у вас есть, должно быть очень сложно реализовать в стиле MVVM/Knockout, потому что у вас нет поддержки, наблюдаемой для выбранных значений переключателя. После того, как вы меняете, что вы можете выбрать несколько способов реализовать требования, в том числе:

  • Создание writeable computeds для отступающих наблюдаемыми, где write бит обновляет родственный наблюдаемых;
  • Создание подписки на все индивидуальные наблюдаемые наблюдения.

Вот пример последнего варианта:

var SimpleListModel = function() { 
 
    var self = this; 
 
    
 
    this.allDriversForPolicy = ko.observableArray([{ 
 
    'id': 'abe', 
 
    'vehicleDriverType': ko.observable('Primary') 
 
    }, { 
 
    'id': 'bob', 
 
    'vehicleDriverType': ko.observable('Secondary') 
 
    }, { 
 
    'id': 'charlie', 
 
    'vehicleDriverType': ko.observable('') 
 
    }]); 
 
    
 
    self.allDriversForPolicy().forEach(function(i) { 
 
    i.vehicleDriverType.subscribe(function(newVal) { 
 
     if (newVal !== 'Primary') return; 
 
     self.allDriversForPolicy().forEach(function(p) { 
 
     if (p !== i && p.vehicleDriverType() === 'Primary') { 
 
      p.vehicleDriverType(''); 
 
     } 
 
     }); 
 
    }); 
 
    }); 
 
}; 
 

 
ko.applyBindings(new SimpleListModel());
pre { background: white; padding: 10px; color: #333; font: 11px consolas; border: 1px solid #ddd; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 

 
<!--ko foreach: allDriversForPolicy--> 
 
<div class="col-md-2"> 
 
    <div class=""> 
 
    <label> 
 
     <input type="radio" value="Primary" data-bind="checked: vehicleDriverType, attr: {name: id}" />Primary</label> 
 
    <label> 
 
     <input type="radio" value="Secondary" data-bind="checked: vehicleDriverType, attr: {name: id}" />Secondary</label> 
 
    <label> 
 
     <input type="radio" value="Ocasional" data-bind="checked: vehicleDriverType, attr: {name: id}" />Ocasional</label> 
 
    <label> 
 
     <input type="radio" value="" data-bind="checked: vehicleDriverType, attr: {name: id}" />None</label> 
 
    </div> 
 
</div> 
 
<!--/ko--> 
 

 
<hr>Debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

PS. Я предлагаю создать отдельную конструкторскую функцию для элементов в этом массиве, что сделает намного более четкий код (вложенные forEach es станут намного лучше, если вы это сделаете).

+0

Ах, простите об этом. В моем примере отсутствует тег изображения (это не было необходимо для проблемы). Мой план состоит в том, чтобы сделать все это миниатюрами и отобразить список выбора, когда вы наводите на него курсор. Нажатие на то, что не является списком переключателей, вызовет диалог загрузки файла, чтобы изменить изображение. Это план в любом случае. – Maleki