Reset модель с angular.js
Я просто пытаюсь использовать значения reset следующим образом:
$scope.initial = [
{
data1: 10,
data2: 20
}
];
$scope.datas= $scope.initial;
$scope.reset = function(){
$scope.datas = $scope.initial;
}
Но это ничего не дает, любая идея исправить это?
angular.module('app', []).controller('MyCtrl', function($scope) {
$scope.initial = [
{
data1: 10,
data2: 20
}
];
$scope.datas= $scope.initial;
$scope.reset = function(){
$scope.datas = $scope.initial;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<div ng-repeat="data in datas">
<input type="text" ng-model="data.data1" />
<input type="text" ng-model="data.data2" />
</div>
<a ng-click="reset()">Reset to initial value</a>
or
<button ng-click="name = initial">Reset to initial value</button>
<hr />
<p ng-repeat="data in datas">{{data.data1}}, {{data.data2}}</p>
</div>
Ответы
Ответ 1
Это действительно вопрос о JavaScript (поэтому я добавил тег "javascript" ). Когда объект JavaScript (такой как массив $scope.initial) присваивается переменной, он присваивается ссылкой, а не копией. Итак, это утверждение
$scope.datas= $scope.initial;
приводит к $scope.datas, указывающему на объект $scope.initial. Любые изменения, внесенные в $scope.datas или $scope.initial, влияют на один и тот же (один) объект. Поскольку ng-модель используется для привязки объектов данных data1 и data2, любые изменения в текстовых вводах изменят элементы данных1 и data2 объекта, которые ссылаются на значения $scope.datas, то есть $scope.initial. Чтобы увидеть это в действии, добавьте следующее в свою скрипту HTML:
<p>{{initial}}</p>
Когда вы меняете значения в текстовых полях, вы увидите, что также изменяется переменная $scope.initial.
@Max предоставил частичный ответ: используйте angular.copy() в функции reset. Однако вам также придется использовать angular.copy() в начальном назначении:
$scope.datas = angular.copy($scope.initial);
Update:
Как показывает @EpokK в своем ответе, альтернативное решение
angular.copy($scope.initial, $scope.datas);
Как поясняет @bekite в своем ответе, решение @EpokK не создает другого объекта.
Полный код
angular.module('app', []).controller('MyCtrl', function($scope) {
$scope.initial = [{
data1: 10,
data2: 20
}];
$scope.datas = angular.copy($scope.initial);
$scope.reset = function () {
$scope.datas = angular.copy($scope.initial);
// or
// angular.copy($scope.initial, $scope.datas);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<div ng-repeat="data in datas">
<input type="text" ng-model="data.data1" />
<input type="text" ng-model="data.data2" />
</div>
<a ng-click="reset()">Reset to initial value</a>
or
<hr />
<p ng-repeat="data in datas">{{data.data1}}, {{data.data2}}</p>{{initial}}
</div>
Ответ 2
Попробуйте изменить функцию reset
, чтобы использовать angular.copy
$scope.reset = function () {
$scope.datas = angular.copy($scope.initial);
};
Ответ 3
@Mark Rajcok:
Не поймите меня неправильно, но я думаю, что
angular.copy($scope.initial, $scope.datas);
не является альтернативным синтаксисом для
$scope.datas = angular.copy($scope.initial);
То, как я это понимаю:
$scope.datas = angular.copy($scope.initial);
Создает копию $scope.initial и присваивает ссылку на $scope.datas.
angular.copy($scope.initial, $scope.datas);
Обновляет значения $scope.datas значениями $scope.initial
См. документы angularjs (http://docs.angularjs.org/api/angular.copy), и там sektion в выражении Return
Возвращает копию или обновленную адресату, если был указан пункт назначения.
Ответ 4
Рабочий синтаксис:
$scope.reset = function () {
angular.copy($scope.initial, $scope.datas);
};
Справочник по API: angular.copy(source[, destination]);
Ответ 5
Рассмотрим следующие кнопки
- Изменить
- Сохранить
- Отмена
Когда пользователь нажимает редактировать и изменяет данные, а затем использует кнопку отменить, чтобы получить старые данные, вот как это можно реализовать.
HTML
<div>
<button data-ng-click="edit()" data-ng-show="!editing">Edit</button>
<button data-ng-click="save()" data-ng-show="editing">Save</button>
<button data-ng-click="cancel()" data-ng-show="editing">Cancel</button>
</div>
AngularJs
$scope.edit = function () {
$scope.editing = true;
$scope.copy = angular.copy($scope.data);
};
$scope.cancel = function () {
$scope.editing = false;
$scope.data = $scope.copy;
};
Ссылки
Ответ 6
Я люблю комментарий Ясира: ясный и лаконичный.
Я определенно предпочитаю копировать значение при начале редактирования, а затем просто заменять ссылку на отмену/сохранение.
Я предпочитаю привязывать локальную копию, а не исходные данные, а затем изменять окончательные данные только при сохранении.
Это предотвратит всевозможные ошибки позже и инкапсулирует поведение редактирования.
Конечная версия:
function initValue() {
$scope.bound = angular.copy($scope.data);
}
function setValue() {
$scope.data = $scope.bound;
}
$scope.edit = function () {
$scope.editing = true;
initValue();
};
$scope.cancel = function () {
$scope.editing = false;
initValue();
};
$scope.save= function () {
$scope.editing = false;
setValue();
};
Ответ 7
Я использовал, как вы все сказали выше, поддерживая резервное копирование, но, используя его, я столкнулся с еще одной проблемой.
Я думал, что если я опубликую его здесь, это будет полезно другим.
У меня есть код раздела профиля, как показано ниже:
var profileBackup ={};
$scope.profileContinue = function()
{
profileBackup = angular.copy($scope.userData.profile);
// profileBackup = $scope.userData.profile;
//other code
}
$scope.profileCancel = function()
{
$scope.userData.profile = profileBackup;
}
Но я был удивлен, увидев, что даже переменная profile неактивной переменной Backup обновлялась, когда модель менялась (в этом случае вернется ссылка)
Затем я изменил свой код следующим образом:
$scope.profileContinue = function()
{
profileBackup = angular.toJson($scope.userData.profile);
// profileBackup = $scope.userData.profile;
//other code
}
$scope.profileCancel = function()
{
$scope.userData.profile = angular.fromJson(profileBackup);
}
пожалуйста, простите меня, если это не имеет никакого смысла.