Второй раскрывающийся список AngularJS не обновляется при изменении первого раскрывающегося списка

Я создаю страницу поиска, на которой пользователь может искать данные, используя предварительно выбранные критерии поиска, перечисленные в первом раскрывающемся списке. В приведенном ниже примере такими критериями являются «Имя», «Страна» и «Национальность».

Когда пользователь выбирает страну или национальность, появляется второй раскрывающийся список для выбора одной из стран/национальностей. Чтобы заполнить этот раскрывающийся список, я использую ng-options с переменной внутри, которая указывает на строку, определенную в контроллере.

Но когда выбран один из этих двух вариантов и вы хотите переключиться на другой, второй раскрывающийся список не обновляется. Значение внутри ngOptions обновляется в HTML, только данные внутри раскрывающегося списка не обновляются.

Когда вы выбираете «Имя» между ними, проблем нет. Кто-нибудь знает, что я могу использовать, чтобы значения во втором раскрывающемся списке обновлялись?

Ниже приведен мой код и работающий плункер: http://plnkr.co/edit/LYpOdoLpgiMeHxlGzmub?p=preview

var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope) {
  
    var vm = this;
    
    vm.search = {id:0, criteria: {}, value: ''};
    
    vm.referenceData = {
      countries: [
        {COUNTRY_ID:1, COUNTRY_NAME: 'UNITED KINGDOM'},
        {COUNTRY_ID:2, COUNTRY_NAME: 'AUSTRALIA'},
        {COUNTRY_ID:3, COUNTRY_NAME: 'SOUTH AFRICA'},
        {COUNTRY_ID:4, COUNTRY_NAME: 'NETHERLANDS'},  
      ],
      nationalities: [
        {NATIONALITY_ID: 1, NATIONALITY_NAME: "BRITISH"},
        {NATIONALITY_ID: 2, NATIONALITY_NAME: "AUSTRALIAN"},
        {NATIONALITY_ID: 3, NATIONALITY_NAME: "SOUTH AFRICAN"},
        {NATIONALITY_ID: 4, NATIONALITY_NAME: "DUTCH"},  
        ]
    };
    
    vm.criteriaList = [
        { name: 'First Name', key: 'FIRST_NAME'},
        { name: 'Country', key: 'COUNTRY_ID', options:'o.COUNTRY_ID as o.COUNTRY_NAME for o in ctrl.referenceData.countries' },
        { name: 'Nationality', key: 'NATIONALITY', options:'o.NATIONALITY_ID as o.NATIONALITY_NAME for o in ctrl.referenceData.nationalities' }
    ];
});
<!DOCTYPE html>
<html>

<head>
  <script data-require="[email protected]" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-app="myApp" ng-controller="SomeController as ctrl">


  <p>Criteria:</p>
  <select ng-model="search.criteria" ng-change="search.value = ''" ng-options="criteria as criteria.name for criteria in ctrl.criteriaList">
    <option value="">- Select Criteria -</option>
  </select>
  
  
  <p>Value:</p>
  <!-- TEXT INPUT -->
  <input type="text" ng-model="search.value" placeholder="Search Value" ng-if="!search.criteria.options" />
  <!-- DROPDOWN INPUT -->
  <select ng-model="search.value" ng-if="search.criteria.options" ng-options="{{search.criteria.options}}"></select>

</html>


person Olafvv    schedule 09.08.2017    source источник
comment
это первый раз, когда я вижу выражение внутри ng-options, я вижу plnkr и меня беспокоит, почему бы не обновить. возможно, причина в том, что ng-options не обрабатывает данные привязки. Возможно, с помощью директивы a можно было бы решить, принудительно обновляя компонент.   -  person Jesus Carrasco    schedule 09.08.2017
comment
не элегантное решение - обрабатывать два раскрывающихся списка: один для национальности, а другой для городов. Я знаю, что это не то, что вы ищете.   -  person Jesus Carrasco    schedule 09.08.2017
comment
вот решение с директивой, как я говорю stackoverflow.com/a/27857228/8303694   -  person Jesus Carrasco    schedule 09.08.2017


Ответы (1)


Это простое решение, вам просто нужна переменная, которая может открываться во втором раскрывающемся списке каждый раз, когда вы переключаетесь. Дому нужно что-то, чтобы заставить его обновиться, так как scope.$apply не происходит.

Планкер работает

Попробуй это:

var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope, $timeout) {

    var vm = this;
    vm.somVal = false; ///ADD THIS
    vm.search = {id:0, criteria: {}, value: ''};

    vm.triggerSomeVal = function(){ ///ADD THIS
      vm.someVal = true;
      $timeout(function(){vm.someVal = false}, 100)
    };

    vm.referenceData = {
      countries: [
        {COUNTRY_ID:1, COUNTRY_NAME: 'UNITED KINGDOM'},
        {COUNTRY_ID:2, COUNTRY_NAME: 'AUSTRALIA'},
        {COUNTRY_ID:3, COUNTRY_NAME: 'SOUTH AFRICA'},
        {COUNTRY_ID:4, COUNTRY_NAME: 'NETHERLANDS'},  
      ],
      nationalities: [
        {NATIONALITY_ID: 1, NATIONALITY_NAME: "BRITISH"},
        {NATIONALITY_ID: 2, NATIONALITY_NAME: "AUSTRALIAN"},
        {NATIONALITY_ID: 3, NATIONALITY_NAME: "SOUTH AFRICAN"},
        {NATIONALITY_ID: 4, NATIONALITY_NAME: "DUTCH"},  
        ]
    };

    vm.criteriaList = [
        { name: 'First Name', key: 'FIRST_NAME'},
        { name: 'Country', key: 'COUNTRY_ID', options:'o.COUNTRY_ID as o.COUNTRY_NAME for o in ctrl.referenceData.countries' },
        { name: 'Nationality', key: 'NATIONALITY', options:'o.NATIONALITY_ID as o.NATIONALITY_NAME for o in ctrl.referenceData.nationalities' }
    ];
});

<p>Criteria:</p>
  <select ng-model="search.criteria" ng-change="search.value = ''; ctrl.triggerSomeVal()" ng-options="criteria as criteria.name for criteria in ctrl.criteriaList">
    <option value="">- Select Criteria -</option>
  </select>


  <p>Value:</p>
  <!-- TEXT INPUT -->
  <input type="text" ng-model="search.value" placeholder="Search Value" ng-if="!search.criteria.options" />
  <!-- DROPDOWN INPUT ADD !someVal-->
  <select ng-model="search.value" ng-if="search.criteria.options && !ctrl.someVal" ng-options="{{search.criteria.options}}"></select>
person Ohjay44    schedule 09.08.2017
comment
вы тестируете решение? копирую код а он не работает. - person Jesus Carrasco; 09.08.2017
comment
Теперь это должно сработать. Я забыл добавить $timeout в контроллер и контекст ctrl в html. - person Ohjay44; 09.08.2017
comment
Вы также можете изменить время ожидания на 100, так что это очень быстро - person Ohjay44; 09.08.2017
comment
Да, похоже, это помогает :) Большое спасибо! Ответ отмечен - person Olafvv; 10.08.2017