#javascript #forms #angularjs
#javascript #формы #angularjs
Вопрос:
У меня есть следующая угловая форма:
<form name="client_form" id="client_form" role="form">
<div class="bb-entry">
<label for="firstname">First Name:*</label>
<input type="text" name="firstname" ng-model="client.first_name" required class="form-control"/>
</div>
<div class="bb-entry">
<label for="lasttname">Last Name:*</label>
<input type="text" name="lastname" ng-model="client.last_name" required class="form-control"/>
</div>
<div class="bb-entry">
<label for="email">E-mail:*</label>
<input type="email" name="email" ng-model="client.email" required class="form-control"/>
</div>
</form>
<button type="button" ng-click="resetForm(client_form)">Clear</button>
Я хотел бы добавить поведение, чтобы, когда пользователи выбирали «Очистить», все данные формы очищались. В настоящее время я написал этот метод:
resetForm: (form) ->
form.submitted = false
form.$setPristine()
angular.copy({}, client)
Однако это очищает весь объект клиента, хотя на самом деле я хочу очистить только атрибуты, на которые ссылаются в моей форме.
Я понимаю, что могу выполнять итерации по каждому атрибуту объекта формы, что дает мне доступ к экземплярам ngModelController как таковым:
resetForm: (form,) ->
form.submitted = false
form.$setPristine()
angular.forEach form, (value, key) ->
if value.hasOwnProperty("$modelValue")
# set model value here?
Но могу ли я на самом деле присвоить значение модели здесь или лучше использовать другой подход?
Комментарии:
1. Почему бы просто не
<input type='reset' value='Clear' />
очистить всю форму, а затем, если вам нужно что-то вызвать при нажатии, просто используйтеonclick
2. Эй, @pattyd, это заметно очищает поля формы, но, похоже, не очищает данные в базовой модели?
3. Вот почему вам нужно установить
onclick
. Установитеonclick
функцию для очистки этих данных
Ответ №1:
Я думаю, вам нужно сначала скопировать клиент, а затем очистить новый объект клиента.
Вот ссылка на скрипку, которая делает что-то очень похожее:http://jsfiddle.net/V44fQ /
$scope.editClient = function(client) {
$scope.edit_client = angular.copy(client);
}
$scope.cancelEdit = function() {
$scope.edit_client = {};
};
<form name="client_form" id="client_form" role="form">
<div class="bb-entry">
<label for="firstname">First Name:*</label>
<input type="text" name="firstname" ng-model="edit_client.first_name" required class="form-control">
</div>
...
<button type="button" ng-click="cancelEdit()">Clear</button>
</form>
Ответ №2:
Я решил проблему, написав две директивы, одну, которая прикреплена к форме, а другую к каждому отдельному входу, который я хочу «сбрасывать». Директива, прикрепленная к форме, затем добавляет метод resetForm() к родительскому контроллеру:
# Adds field clearing behaviour to forms.
app.directive 'bbFormResettable', ($parse) ->
restrict: 'A'
controller: ($scope, $element, $attrs) ->
$scope.inputs = []
$scope.resetForm = () ->
for input in $scope.inputs
input.getter.assign($scope, null)
input.controller.$setPristine()
registerInput: (input, ctrl) ->
getter = $parse input
$scope.inputs.push({getter: getter, controller: ctrl})
# Registers inputs with the bbFormResettable controller allowing them to be cleared
app.directive 'bbResettable', () ->
restrict: 'A',
require: ['ngModel', '^bbFormResettable'],
link: (scope, element, attrs, ctrls) ->
ngModelCtrl = ctrls[0]
formResettableCtrl = ctrls[1]
formResettableCtrl.registerInput(attrs.ngModel, ngModelCtrl)
Возможно, это излишне, но это решение гарантирует, что будут очищены только указанные атрибуты, а не весь клиентский объект.
Ответ №3:
Не нужно усложнять. Просто очистите переменные области видимости в вашем контроллере.
Простой JS:
$scope.resetForm = function() {
$scope.client.first_name = '';
$scope.client.last_name = '';
$scope.client.email = '';
}
При желании вы можете проанализировать объект $scope.client и присвоить свойствам значение false (например, если форма динамическая).
Вот простой пример:http://jsfiddle.net/DLL3W /
Комментарии:
1. Это довольно уродливое решение. Поддерживать (или писать, если на то пошло) это, когда у вас большая форма, — это беспорядок.
2. @dirkk Вот почему я сказал, что есть много способов справиться с этим… Я просто дал оператору панель запуска, чтобы он мог получить рабочий код и двигаться дальше. Лично я бы просто установил
$scope.client
в пустой объект и никогда больше не беспокоился об этой форме.3. В этом случае я не хочу устанавливать ‘$scope.client’ для пустого объекта, поскольку есть атрибуты, которые я хочу сохранить. В идеале я хочу очистить только атрибуты, используемые в форме.
4. @LukeFerguson Да, я понятия не имею, как выглядит приложение в целом, поэтому не хотел углубляться в это. Но в любом случае, с этого момента у вас есть множество вариантов — вы можете очистить необходимые свойства вручную; сохранить их в массиве и сверить с ними объект client; создать новую переменную области видимости только для формы и обновить клиент из нее; и т.д…