Angularjs вернуть выбранное значение элемента управления, вложенного в ng-repeat, при отмене диалога

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

Вот что у меня есть на данный момент:

Соответствующий HTML:

<table>
  <tbody>
    <tr ng-repeat="application in rows">
      <td>
        <select
                ng-model="application.selectedVersion"
                ng-options="apk.versionName for apk in application.versions | orderBy : 'id' : true"
                ng-init="application.selectedVersion=application.versions.filter(currentVersion, application.apkUpdates)[0]"
                ng-change="selectionChanged(application, '{{application.selectedVersion}}')"
                style="padding:0 1em;" />
      </td>
    </tr>
  </tbody>
</table>

Логика Javascript:

$scope.selectionChanged = function(application, previousVersion) {
  var dialog = confirm('Change version?');

  if (dialog) {
    console.log('change version confirmed');
  } else {
    application.selectedVersion = previousVersion;
  }
};

Передача '{{application.selectedVersion}}' в функцию вместо application.selectedVersion передает ранее выбранное значение вместо текущего (объяснено здесь: https://stackoverflow.com/a/45051464/2596580).

Когда я изменяю значение выбора, выполняю диалоговое взаимодействие и отменяю его, я пытаюсь вернуть значение, установив application.selectedVersion = angular.copy(previousVersion);. Я вижу, что значение правильное, отладив javascript, но для ввода выбора установлено пустое значение, а не фактическое значение.

Что я делаю неправильно?

Демонстрация JSFiddle: https://jsfiddle.net/yt4ufsnh/

2
0
249
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы должны исправить пару вещей в своей реализации

  1. Когда вы передаете '{{application.selectedVersion}}' в метод selectionChanged, он становится необработанным string. Когда вы повторно назначаете application.selectedVersion, вы должны сначала проанализировать этот previousVersion на JSON, используя метод JSON.parse.
  2. Используйте track by apk.id в коллекции ng-options. Это необходимо, потому что проанализированный объект JSON не распознается как тот же экземпляр объекта, который использовался для создания выборки, поэтому это работает так, как если бы переопределение встроенной функции equals для использования только ее свойства id

Окончательный вариант

ng-options="apk.versionName for apk in (application.versions | 
                                           orderBy : 'id' : true) track by apk.id" 

Код

$scope.selectionChanged = function(application, previousVersion) {
    var dialog = confirm('Change version?');
    if (dialog) {
      console.log('change version confirmed');
    } else {
      application.selectedVersion = previousVersion ? JSON.parse(previousVersion) : null;
    }
};

Обновленная рабочий пример

Это работает для фактической установки значения на входе выбора, но устанавливает текущее значение. Я хочу установить предыдущее значение (т.е. отменить обновление ng-change для просмотра). Я отредактировал вопрос, чтобы прояснить эту деталь.

Netherdan 13.09.2018 20:16

@Netherdan Не могли бы вы взглянуть на обновленный ответ?

Pankaj Parkar 13.09.2018 21:01

Я отправлял тот же ответ, когда заметил ваше обновление. Причина этого в том, что проанализированный объект JSON не равен объекту, используемому для создания выборки (т.е.JSON.parse(previousVersion) === application.versions[previousVersionIndex] возвращает false), поэтому он не распознает его как тот же экземпляр. Предложение track by принудительно отслеживает объект по значению id, поэтому, возможно, даже необработанный JSON.parse ("{id: x}") будет работать, но мне это не нужно и никогда не буду этого делать. Ваше решение работает должным образом. Спасибо!

Netherdan 13.09.2018 21:38

@Netherdan не стесняйтесь редактировать ответ :) Я принимаю редактирование

Pankaj Parkar 14.09.2018 12:34

если вы просто удалите условие else из своего кода javascript, вы сможете достичь нужного поведения.

Ваш окончательный код должен быть:

$scope.selectionChanged = function(application, previousVersion) {
  var dialog = confirm('Change version?');

  if (dialog) {
    console.log('change version confirmed');
  }
};

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

Netherdan 13.09.2018 20:26

Другие вопросы по теме