Невозможно программно использовать двухстороннюю привязку к элементу SELECT в Angular JS

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

Я обнаружил, что некоторые из них используют ng-repeat для элемента OPTION, но я: а) не смог заставить его работать, и б) не похоже на «Angular Way».

HTML-код:

<div ng-controller="SIController">
<select id="current-command" ng-model="currentCommand"
ng-options="c as c.label for c in availableCommands track by c.id"></select>
<button ng-click="changeSelectedOption()">Select "open"</button>

Controller Code:

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

function SIController($scope) {

    $scope.availableCommands = [
        {id: 'edit',        label: 'Edit'},
        {id: 'open',        label: 'Open'},
        {id: 'close',       label: 'Close'}
    ];

    $scope.currentCommand = "close";
    $scope.changeSelectedOption = function() {
        $scope.currentCommand = 'open';
    };  
};

Я могу убедиться, что $scope.currentCommand изменяется при нажатии кнопки, но ВАРИАНТ, похоже, не выбирается.

Скрипка здесь


person Kevin Schroeder    schedule 28.07.2015    source источник


Ответы (2)


Есть ли рабочая скрипка: http://jsfiddle.net/bzhkkw18/9/

Чтобы объяснить, что я сделал, есть имя функции, которое не совпадает на ng-click и в контроллере.

И основная часть заключалась в определении вашего варианта. В вашем ng-options вы устанавливаете все объекты. Если это то, что вы действительно хотите, вы должны сделать то же самое в своем currentCommand следующим образом:

//Object 2 is close
$scope.currentCommand = $scope.availableCommands[2];
person Pierre-Alexandre Moller    schedule 28.07.2015
comment
Спасибо. Я думаю, что часть моей проблемы заключается в том, что когда данные выходят из выбранного объекта (т.е. щелкают по нему), они выходят в одном формате, но для их выбора с помощью JavaScript требуется другой формат. Похоже, мне нужно сделать минимальный рефакторинг. - person Kevin Schroeder; 28.07.2015
comment
Пожалуйста. Тот же формат требуется в currentCommand. А ведь было по другому, на твоем ng-model у тебя все обьект. И когда вы его устанавливаете, вы ставите только метку. Вам нужно только согласовать значения. Если вы хотите сохранить весь объект, мой ответ в порядке. Если вы просто хотите сохранить метку, необходимо выполнить рефакторинг. - person Pierre-Alexandre Moller; 28.07.2015
comment
У меня вопрос вдогонку. В моем реальном приложении привязка данных работает, но это происходит только тогда, когда я вызываю какую-то другую команду. Чтобы заставить его работать при изменении модели, мне нужно вызвать $scope.$apply(), но я не понимаю, почему, и я бы предпочел, чтобы это было автоматически. Метод вызывается из сторонней библиотеки, которая обрабатывает привязки клавиш. - person Kevin Schroeder; 30.07.2015

У меня недавно была аналогичная проблема. Взгляните на мой ответ. Вы должны изменить способ, которым вы определили ng-options.

function MyCtrl($scope) {
    $scope.values = [
        {name : "Daily", id : 1},
        {name : "Weekly", id : 2},
        {name : "Monthly", id : 3},
        {name : "Yearly", id : 4}];
    $scope.selectedItem = $scope.values[0].id;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
    <select ng-model="selectedItem" ng-options="selectedItem.id as selectedItem.name for selectedItem in values"></select>
    selectedItem: {{selectedItem}}
</div>

person Andrzej Gis    schedule 28.07.2015
comment
Это действительно будет зависеть от того, что вы хотите в selectedItem. Если вам нужен идентификатор, это хороший способ. Если вам нужен весь объект, вам нужно сохранить первый синтаксис. - person Okazari; 28.07.2015
comment
@Okazari Когда вы делаете «ng-options = selectedItem as ....», он привязывается к объекту whle. - person Andrzej Gis; 28.07.2015
comment
Да, но я просто хотел поставить предупреждение. Ваш пример будет только вводить в selectedItem, и это может быть не то, что нужно оператору. - person Okazari; 28.07.2015