несколько радиогрупп внутри одного ng-repeat не работают

Я не могу понять это, не уверен, почему это не работает. У меня есть ситуация, когда мне нужно иметь родительские флажки, и когда они выбраны, дочерние переключатели выпадают, где им нужно выбрать один элемент для каждого выбранного ими флажка. Эта часть работает нормально, проблема в том, что когда выбрано более одного флажка, переключатели действуют так, как будто все они находятся под одним и тем же именем, даже если это не так... когда выбран один, все остальные становятся невыбранными, когда я только хотите, чтобы другие под этим именем стали невыбранными. Шаблон написан для использования в форме, поэтому вы видите, что ng-модель может выглядеть странно, в основном она использует модель, используемую для формы (отличная библиотека динамических форм js для angularjs)

Вот массивы, загружаемые в ng-repeats:

to.parents = [{name: 'IR', value: 'IR'}, {name: 'IS', value: 'IS'}, {name: 'IP', value: 'IP'}];

to.children = [{name: 'New', value: 'IRNew', parent: 'IR'}, {name: 'Maintenance', value: 'IRMain', parent: 'IR'}, {name: 'Existing', value: 'IRExist', parent: 'IR'}, {name: 'New', value: 'ISNew', parent: 'IS'}, {name: 'Maintenance', value: 'ISMain', parent: 'IS'}, {name: 'Existing', value: 'ISExist', parent: 'IS'}, {name: 'New', value: 'IPNew', parent: 'IP'}, {name: 'Maintenance', value: 'IPMain', parent: 'IP'}, {name: 'Existing', value: 'IPExist', parent: 'IP'}]

Вот шаблон ниже:

<div class="radio-group row" ng-class="{\'has-error\': options.formControl.$invalid}">
    <label class="control-label">{{to.label}}{{to.required ? \'*\' : \'\'}}</label>
</div>
<div class="row" style="margin-left:10px;">
    <div class="{{to.col}}" ng-repeat="parent in to.parents track by $index" style="margin-top: 5px; margin-left:0px;" 
     ng-class="{\'checkbox\': !to.inline, \'checkbox-inline\':to.inline}">
        <input type="checkbox" id="{{parent.value}}{{$index}}" 
         class="checkbox-inline styled styled-primary multiCheck{{$index}}" 
         aria-describedby="{{id}}_description" ng-value="parent.name" 
         ng-model="$parent.model[$parent.options.key || $parent.$index][parent.value]"
         ng-disabled="{{parent.disabled}}">
         <label for="{{parent.value}}{{$index}}" style="font-weight: normal;">{{parent.name}}</label>
         <p id="{{id}}_description" class="help-block" ng-if="parent.desc">{{parent.desc}}</p>
         <div class="radio" style="margin-left:20px; margin-top: 10px;" 
         ng-repeat="child in to.children track by $index"
         ng-class="{\'radio\': !to.radInline, \'radioinline\':to.radInline}" 
         ng-if="child.parent === parent.name && $parent.model[$parent.options.key|| $parent.$index][parent.value]">
            <div class="radio-group {{to.colChild}} pull-left"    
             style="margin-top: 5px; margin-bottom: 10px;">
               <input type="radio" name="{{child.parent}}" id="{{child.value}}{{parent.value}}{{$index}}" 
                class="radio radio{{$index}}" ng-value="child.value" ng-model="model[parents.key]">
               <label for="{{child.value}}{{parent.value}}{{$index}}">{{child.name}}</label>
            </div>
          </div>
     </div>
</div>

Таким образом, в основном имена радиогрупп совпадают с родительским именем, поэтому дочерние элементы в IP имеют имя IP, дочерние элементы в IR имеют имя IR, а дочерние элементы в IS имеют IS в качестве имени... но все они по-прежнему действовать так, как будто они являются частью одного и того же имени --- это не имеет смысла для меня, потому что радиокнопки должны быть сгруппированы по их имени ... любая помощь будет принята с благодарностью!

PS: Пожалуйста, не говорите мне об использовании встроенных стилей --- я знаю, что это не лучшая практика, однако у меня нет другого выбора, потому что компания, в которой я работаю, имеет глобальные таблицы css, которые являются единственными, на которые обращают внимание, поэтому любые изменения в этом должны быть сделаны встроенными.


person MattE    schedule 18.03.2018    source источник


Ответы (1)


https://plnkr.co/edit/Id1HxsRvYECQYOe3oMKD?p=preview

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

Сопоставьте дочерние элементы либо с исходным массивом родителей, либо создайте новый:

  parents = parents.map(function(p) {
    p.children = children.filter(function(c) {
      return c.parent == p.name;
    });
    return p;
  });

Теперь ваш новый массив родителей выглядит так:

  /*
  parents = [
    {
      name: 'IR', 
      value: 'IR',
      children: [
        {name: 'New', value: 'IRNew', parent: 'IR'}, 
        {name: 'Maintenance', value: 'IRMain', parent: 'IR'}, 
        {name: 'Existing', value: 'IRExist', parent: 'IR'}, 
      ]
    }, 
    {
      name: 'IS', 
      value: 'IS',
      children: [
        {name: 'New', value: 'ISNew', parent: 'IS'}, 
        {name: 'Maintenance', value: 'ISMain', parent: 'IS'}, 
        {name: 'Existing', value: 'ISExist', parent: 'IS'}
      ]
    }, 
    {
      name: 'IP', 
      value: 'IP'
      children: [
        {name: 'New', value: 'IPNew', parent: 'IP'}, 
        {name: 'Maintenance', value: 'IPMain', parent: 'IP'}, 
        {name: 'Existing', value: 'IPExist', parent: 'IP'}
      ]
    }
  ]; */

У каждого флажка есть собственные дочерние элементы, которые легко отображать в разметке. Я значительно упростил его, сведя его к простым вещам, которые нам нужны для функциональности:

<form>
  <div ng-repeat="p in parents track by $index">
    <label for="">{{p.name}}</label>
    <input type="checkbox" name="" id="" value="" ng-model="p.isChecked" />
    <div ng-repeat="c in p.children track by $index" ng-show="p.isChecked">
      <label for="">{{c.name}}</label>
      <input type="radio" name="" id="" ng-value="c.value" ng-model="p.radioChoice"/>
    </div>
  </div>
</form>

Обратите внимание на isChecked и radioChoice для значения модели. Angular добавит их к родительскому объекту, как только будут определены значения для модели.

Это уже работает как есть, и мы даже не назвали радиоприемники. Обратите внимание, что ng-model для радиоприемников принадлежит РОДИТЕЛЮ. Все, что нам действительно нужно от ребенка, — это ценность, которую должно представлять каждое радио.

person Pop-A-Stash    schedule 18.03.2018
comment
Превосходно! Я даже не думал добавлять массив к родительскому массиву... на самом деле это намного проще... отлично работает, спасибо за ответ! - person MattE; 18.03.2018