Очистка данных в угловой форме

#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; создать новую переменную области видимости только для формы и обновить клиент из нее; и т.д…