Привязать ng-options к вложенному массиву внутри объекта JSON, внутри ng-repeat

Это мой первый вопрос, поэтому, пожалуйста, будьте нежны со мной! Я надеюсь, что вы можете помочь.

Я пытаюсь определить поле выбора (раскрывающееся меню) в моем представлении HTML с помощью ng-repeat, чтобы я мог создать выбор для каждого элемента в массиве. Я успешно добился этого, но мои проблемы возникают, когда я пытаюсь получить нужные мне параметры в каждом из вариантов выбора.

Массив, который я использую{ "field1": 1, "field2": "Value01", "field3": "Value02", "refFields": [ { "fieldId": 100, "fieldValue": "fieldValueA" }, { "fieldId": 101, "fieldValue": "fieldValueB" } ] }, etc...

Мне нужен выбор для каждого элемента на «верхнем уровне» массива, и в каждом поле выбора значения, которые должны отображаться, должны быть fieldValue из вложенного массива refFields.

Мой текущий (сломанный) код дает довольно хреновые результаты. Вот код:

<div ng-repeat="fk in fks">
        <ng-form name="fksForm">
            <select name="fkselect" ng-model="fk" ng-options="item as item.refFields for item in fks">                
            </select>
        </ng-form>
    </div>  

Может ли кто-нибудь дать мне некоторое представление о том, возможно ли это? Я не думаю, что выравнивание данных подходит для этого конкретного приложения. Я пробовал довольно много разных вещей, включая передачу индекса в ng-options, что, как вы могли ожидать, дало довольно сомнительные результаты. Я также пробовал это, что не дает мне никакого полезного результата.

ng-options="item as item.refFields.fieldValue for item in fks"

Вот мой JSFiddle: вложенный массив JSON ng-option в ng-repeat

Заранее большое спасибо за любые предложения!


person bb464    schedule 09.06.2015    source источник
comment
Из вашего примера неясно, как значения в retFields соответствуют приведенным выше значениям, но я бы предложил некоторую предварительную обработку данных в вашем контроллере в более стандартный формат, и тогда это должно быть прямолинейно.   -  person Scott    schedule 10.06.2015


Ответы (2)


С помощью Underscore.js вы можете подготовить свои данные для ng-options.

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

Я создал два массива: один с именами полей, которые используются для ng-repeat, а второй массив содержит refFields для параметров.

С помощью $index вы можете получить текущий индекс ng-repeat для доступа к refFields.

Я не уверен, правильно ли я создал это, потому что я не знаю, что вы делаете со значениями field1, field2, field3.

Взгляните на этот jsfiddle или на демо ниже (тот же код).

var myApp = angular.module('myApp', []);

myApp.controller('DetailsCtrl', ['$scope', function($scope) {
    var data = [
  {
    "field1": 1,
    "field2": "Value01",
    "field3": "Value02",
    "refFields": [
      {
        "fieldId": 100,
        "fieldValue": "fieldValueA"
      },
      {
        "fieldId": 101,
        "fieldValue": "fieldValueB"
      }
    ]
  },
  {
    "field1": 2,
    "field2": "Value03",
    "field3": "Value04",
    "refFields": [
      {
        "fieldId": 102,
        "fieldValue": "fieldValueA"
      },
      {
        "fieldId": 103,
        "fieldValue": "fieldValueB"
      },
      {
        "fieldId": 104,
        "fieldValue": "fieldValueC"
      },
      {
        "fieldId": 105,
        "fieldValue": "fieldValueD"
      }
    ]
  },
  {
    "field1": 3,
    "field2": "Value05",
    "field3": "Value06",
    "refFields": [
      {
        "fieldId": 106,
        "fieldValue": "fieldValueA"
      },
      {
        "fieldId": 107,
        "fieldValue": "fieldValueB"
      }
    ]
  }
];
    $scope.fks = _.map(data, function(field) {
        return _.omit(field, ['field1', 'field2', 'field3']).refFields; // only refFields
    });
    console.log($scope.fks);
    $scope.fields = _.map(data, 
    function(field) {
        console.log(field);
        return [field.field1, field.field2, field.field3];
    }
    );
    //console.log(results)
    $scope.dropdown = {};
    
    $scope.changedValue = function(index) {
        console.log(index, $scope.dropdown);
        console.log($scope.dropdown[index]);
    }
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="DetailsCtrl">
<form novalidate class="form-vertical" ng-show="!loading" name="detailsForm" ng-controller="DetailsCtrl">
    <!--<pre>{{fks |json}}</pre>-->
      <div ng-repeat="fk in fields">
          <ng-form name="fksForm">
              <label>{{fk}}</label>
                <select name="fkselect" ng-model="dropdown[$index]" ng-options="item.fieldValue for item in fks[$index]" ng-change="changedValue($index)">
                </select>
            </ng-form>
        </div>  
</form>
</div>

person AWolf    schedule 09.06.2015
comment
Большое спасибо, это дало мне то, что мне нужно, чтобы получить вложенные значения в поля выбора. Я не знал, что могу использовать $index в ng-options. Я также рассмотрю underscore.js более подробно для будущего использования, однако я постараюсь, где это возможно, в будущем преобразовать данные в более стандартный формат. - person bb464; 10.06.2015

С вашими данными все в порядке, и есть более простой способ: использовать этот fk и получить refFields непосредственно из него, так что ng-options="item as item.fieldValue for item in fk.refFields".

Для полного кода:

<div ng-app="myApp" ng-controller="myCtrl">
    <div ng-repeat="fk in fks">
        <label>{{fk.field2}}</label>
        <select ng-model="fk.selectedItem" ng-options="item as item.fieldValue for item in fk.refFields">              
        </select>      
    </div>  
</div>

И данные, на которые вы можете просто ссылаться напрямую:

angular.module('myApp',[])
.controller('myCtrl',function($scope,$timeout) {
    $scope.fks = [
      {
        "field1": 1,
        "field2": "Value01",
        "field3": "Value02",
        "refFields": [
          { "fieldId": 100,  "fieldValue": "1fieldValueA" },
          { "fieldId": 101, "fieldValue": "1fieldValueB" }
        ]
      },
      {
        "field1": 2,
        "field2": "Value03",
        "field3": "Value04",
        "refFields": [
          { "fieldId": 102, "fieldValue": "2fieldValueA" },
          { "fieldId": 103, "fieldValue": "2fieldValueB" },
          { "fieldId": 104, "fieldValue": "2fieldValueC" },
          { "fieldId": 105, "fieldValue": "2fieldValueD" }
        ]
      },
      {
        "field1": 3,
        "field2": "Value05",
        "field3": "Value06",
        "refFields": [
          { "fieldId": 106, "fieldValue": "3fieldValueA" },
          { "fieldId": 107, "fieldValue": "3fieldValueB" }
        ]
      }
    ];
});

И, конечно же, скрипка.

Теперь только не спрашивайте меня, как инициализировать выбор конкретного элемента в таких списках: это то, что я здесь искал.

person monty    schedule 06.10.2015