IT TIP

양식을 원래 상태로 재설정 (AngularJS 1.0.x)

itqueen 2020. 11. 23. 20:42
반응형

양식을 원래 상태로 재설정 (AngularJS 1.0.x)


양식 필드를 원시 상태 (더티 상태 재설정)로 재설정하는 기능은 AngularJS 1.1.x의 로드맵에 있습니다. 불행히도 이러한 기능은 현재 안정 릴리스에서 누락되었습니다.

AngularJS 1.0.x의 모든 양식 필드를 초기 상태로 재설정하는 가장 좋은 방법은 무엇입니까?

이것이 지시문이나 다른 간단한 해결 방법으로 해결할 수 있는지 알고 싶습니다. 원래 AngularJS 소스를 건드리지 않고도 솔루션을 선호합니다. 문제를 명확히하고 설명하기 위해 JSFiddle에 대한 링크. http://jsfiddle.net/juurlink/FWGxG/7/

원하는 기능은에 로드맵 - http://blog.angularjs.org/2012/07/angularjs-10-12-roadmap.html
기능 요청 - https://github.com/angular/angular.js/issues/856
제안 된 솔루션 풀 요청-https : //github.com/angular/angular.js/pull/1127

가능한 해결 방법으로 업데이트 됨

충분한 해결 방법이 있습니까?

방금 HTML 부분을 다시 컴파일하고 DOM에 다시 넣을 수 있다는 것을 알아 냈습니다. 작동하며 일시적인 해결책으로는 괜찮지 만 주석에서 @blesh가 언급했듯이 :

컨트롤러는 DOM이 아닌 비즈니스 로직에만 사용해야합니다!

<div id="myform">
  <form class="form-horizontal" name="form">
  </form>
</div>

그리고 내 컨트롤러에서 resetForm():

  • 손대지 않은 원본 HTML 저장
  • 저장된 원본 HTML 다시 컴파일
  • DOM에서 현재 양식 제거
  • 새로 컴파일 된 템플릿을 DOM에 삽입

자바 스크립트 :

var pristineFormTemplate = $('#myform').html();
$scope.resetForm = function () {
    $('#myform').empty().append($compile(pristineFormTemplate)($scope));
}

해결 방법이없는 솔루션

해결 방법없이 AngularJS를 사용하는 솔루션을 생각해 냈습니다. 여기서 트릭은 AngularJS 기능을 사용하여 동일한 이름을 가진 둘 이상의 지시문을 갖는 것입니다.

다른 사람들이 언급했듯이 실제로 양식을 재설정 할 수있는 AngularJS 1.1.x 브랜치로 만든 풀 요청 ( https://github.com/angular/angular.js/pull/1127 )이 있습니다. 이 풀 요청에 대한 커밋은 ngModel 및 form / ngForm 지시문을 변경합니다 (링크를 추가하고 싶었지만 Stackoverflow는 두 개 이상의 링크를 추가하는 것을 원하지 않습니다).

이제 자체 ngModel 및 form / ngForm 지시문을 정의하고 pull 요청에 제공된 기능으로 확장 할 수 있습니다.

이러한 지시문을 resettableForm이라는 AngularJS 모듈에 래핑했습니다. 이 모듈을 프로젝트에 포함하기 만하면됩니다. AngularJS 버전 1.0.x는 이와 관련하여 마치 Angular 1.1.x 버전 인 것처럼 작동합니다.

''1.1.x로 업데이트 한 후에는 코드를 업데이트 할 필요도없고 모듈 만 제거하면 완료됩니다! ''

또한이 모듈은 양식 재설정 기능을 위해 1.1.x 분기에 추가 된 모든 테스트를 통과합니다.

내가 만든 jsFiddle ( http://jsfiddle.net/jupiter/7jwZR/1/ ) 의 예제에서 작동하는 모듈을 볼 수 있습니다 .

1 단계 : 프로젝트에 resettableform 모듈 포함

(function(angular) {

// Copied from AngluarJS
function indexOf(array, obj) {
  if (array.indexOf) return array.indexOf(obj);

  for ( var i = 0; i < array.length; i++) {
    if (obj === array[i]) return i;
  }
  return -1;
}

// Copied from AngularJS
function arrayRemove(array, value) {
  var index = indexOf(array, value);
  if (index >=0)
    array.splice(index, 1);
  return value;
}

// Copied from AngularJS
var PRISTINE_CLASS = 'ng-pristine';
var DIRTY_CLASS = 'ng-dirty';

var formDirectiveFactory = function(isNgForm) {
    return function() {
        var formDirective = {
            restrict: 'E',
            require: ['form'],
            compile: function() {
                return {
                    pre: function(scope, element, attrs, ctrls) {
                        var form = ctrls[0];
                        var $addControl = form.$addControl;
                        var $removeControl = form.$removeControl;
                        var controls = [];
                        form.$addControl = function(control) {
                            controls.push(control);
                            $addControl.apply(this, arguments);
                        }
                        form.$removeControl = function(control) {
                            arrayRemove(controls, control);
                            $removeControl.apply(this, arguments);
                        }
                        form.$setPristine = function() {
                            element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
                            form.$dirty = false;
                            form.$pristine = true;
                            angular.forEach(controls, function(control) {
                                control.$setPristine();
                            });
                        }
                    },
                };
            },
        };
        return isNgForm ? angular.extend(angular.copy(formDirective), {restrict: 'EAC'}) : formDirective;
    };
}
var ngFormDirective = formDirectiveFactory(true);
var formDirective = formDirectiveFactory();
angular.module('resettableForm', []).
    directive('ngForm', ngFormDirective).
    directive('form', formDirective).
    directive('ngModel', function() {
        return {
            require: ['ngModel'],
            link: function(scope, element, attrs, ctrls) {
                var control = ctrls[0];
                control.$setPristine = function() {
                    this.$dirty = false;
                    this.$pristine = true;
                    element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
                }
            },
        };
    });
})(angular);

2 단계 : 컨트롤러에 모델을 재설정하는 방법 제공

양식을 재설정 할 때 모델을 재설정해야합니다. 컨트롤러에서 다음과 같이 작성할 수 있습니다.

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

function MyCtrl($scope) {
    $scope.reset = function() {
        $scope.form.$setPristine();
        $scope.model = '';
    };
}

3 단계 : HTML 템플릿에이 메서드 포함

<div ng-app="myApp">
<div ng-controller="MyCtrl">
<form name="form">
    <input name="requiredField" ng-model="model.requiredField" required/> (Required, but no other validators)
    <p ng-show="form.requiredField.$errror.required">Field is required</p>
    <button ng-click="reset()">Reset form</button>
</form>
<p>Pristine: {{form.$pristine}}</p>
</div>
</dvi>

Angular의 이후 버전 (예 : 1.1.5)에서는 $setPristine양식을 호출 할 수 있다는 점을 언급 할 가치가 있다고 생각합니다 .

$scope.formName.$setPristine(true)

이렇게하면 모든 양식 컨트롤도 원래 상태로 설정됩니다.

FormController. $ setPristine


편집 ... 적절하지 않았기 때문에 내 이전 답변을 제거하고 있습니다.

나는 실제로이 문제를 직접 만났고 여기에 내 해결책이 있습니다. 각도에 대한 확장 방법을 만들었습니다. 나는 $ scope.form. $ setValidity ()가 (역으로)하고있는 일을 조금 따라 가면서 그렇게했습니다.

작동중인 plnkr 데모입니다.

내가 만든 도우미 방법은 다음과 같습니다. 해킹이지만 작동합니다.

angular.resetForm = function (scope, formName, defaults) {
    $('form[name=' + formName + '], form[name=' + formName + '] .ng-dirty').removeClass('ng-dirty').addClass('ng-pristine');
    var form = scope[formName];
    form.$dirty = false;
    form.$pristine = true;
    for(var field in form) {
      if(form[field].$pristine === false) {
        form[field].$pristine = true;
      }
      if(form[field].$dirty === true) {
        form[field].$dirty = false;
      }
    }
    for(var d in defaults) {
      scope[d] = defaults[d];
    }
};

바라건대 이것은 누군가에게 도움이되기를 바랍니다.


양식 필드는 $ 범위 내의 변수에 연결되어야합니다. 변수를 재설정하여 양식을 재설정 할 수 있습니다. $ scope.form과 같은 단일 개체 여야합니다.

Lets say you have a simple form for a user.

app.controller('Ctrl', function Ctrl($scope){
  var defaultForm = {
    first_name : "",
    last_name : "",
    address: "",
    email: ""
  };
  $scope.resetForm = function(){
    $scope.form = defaultForm;
  };
});

This will work great as long as your html looks like:

<form>
  <input ng-model="form.first_name"/>
  <input ng-model="form.last_name"/>
  <input ng-model="form.address"/>
  <input ng-model="form.email"/>
  <button ng-click="resetForm()">Reset Form</button>
</form>

Maybe I'm not understanding the issue here, so if this does not address your question, could you explain why exactly?


Here I have found a solution for putting the from to its pristine state.

var def = {
    name: '',
    password: '',
    email: '',
    mobile: ''
};

$scope.submited = false;

$scope.regd = function (user) {
    if ($scope.user.$valid) {
        $http.post('saveUser', user).success(function (d) {
            angular.extend($scope.user, def);
            $scope.user.$setPristine(true);
            $scope.user.submited = false;
        }).error(function (e) {});
    } else {
        $scope.user.submited = true;
    }
};

Just write angular.extends(src,dst) ,so that your original object is just extends the blank object, which will appear as blank and rest all are default.


Using an external directive and a lot of jquery

app.controller('a', function($scope) {
    $scope.caca = function() {
        $scope.$emit('resetForm');
    }
});

app.directive('form', function() {
    return {
        restrict: 'E',
        link: function(scope, iElem) {
            scope.$on('resetForm', function() {
                iElem.find('[ng-model]').andSelf().add('[ng-form]').each(function(i, elem) {
                    var target = $(elem).addClass('ng-pristine').removeClass('ng-dirty');
                    var control = target.controller('ngModel') || target.controller('form');
                    control.$pristine = true;
                    control.$dirty = false;
                });
            });
        }
    };
});

http://jsfiddle.net/pPbzz/2/


The easy way: just pass the form into the controller function. Below the form "myForm" is referenced by this, which is equivalent to $scope.

<div ng-controller="MyController as mc">
    <ng-form name="myform">
        <input ng-model="mc.myFormValues.name" type="text" required>
        <button ng-click="mc.doSometing(this.myform)" type="submit" 
                ng-disabled="myform.$invalid||myform.$pristine">Do It!</button>
    </ng-form>
</div>

The Controller:

function MyController(MyService) {
    var self = this;
    self.myFormValues = {
        name: 'Chris'
    };
    self.doSomething = function (form) {
        var aform = form;
        MyService.saveSomething(self.myFromValues)
            .then(function (result) {
                ...
                aform.$setPristine();
            }).catch(function (e) {
                ...
            aform.$setDirty();
        })
    }
}

참고URL : https://stackoverflow.com/questions/12603914/reset-form-to-pristine-state-angularjs-1-0-x

반응형