기본 콘텐츠로 건너뛰기

[Guide] 9_Angular Form

[Guide] 9_Angular Form

input, select, textarea는 사용자의 데이터의 입력을 위한 엘리먼트입니다. Angular는 이 핵심기능을 한곳에 모아서 다양한 기능을 제공하고 있습니다.

사용자가 입력하는 데이터의 검증을 프레임워크에서 제공해줘서 조금 더 좋은 사용자 환경은 물론 개발자에게도 개발의 편의를 제공하고 있습니다.

Simple form

ngModel을 통해 directive의 핵심인 양방향 데이터 바인딩을 이해할수있습니다. ngModel의 경우에는 양방향 데이터 바인딩을 통해서 view와 모델간의 데이터의 일관성을 유지하고 있습니다.

index.html Name: E-mail: Gender: male female form = {{user | json}} master = {{master | json}}

$scope.update = function(user) { $scope.master = angular.copy(user); };

$scope.reset = function() { $scope.user = angular.copy($scope.master); };

$scope.reset(); }]);

novalidate를 통해서 브라우저 자체의 검증기능을 제거했습니다. 위의 폼에서 이메일의 경우에는 이메일의 폼에 어긋날경우 실제 데이터로 인식을 하지않습니다.

Using CSS classes

css 클래스를 ngModel에 추가하여 form을 꾸미는것을 허용합니다.

ng-valid: 모델이 유효한 경우

ng-invalid: 모델이 유요하지 않은 경우

ng-valid-[key]: 유효한 key값은 $setValidity 를 통해 설정됩니다.

ng-invalid-[key]: 유효하지 않은 key값은 $setValidity 를 통해 설정됩니다.

ng-pristine: 사용자의 입력이 받기전의 상태

ng-dirty: 사용자의 입력이 들오왔던 경우

ng-touched: 사용자의 입력이 막 마친경우

ng-untouched: 사용자의 입력이 아직 마치지 않은 상태

ng-pending: 어떠한 $asyncValidators 가 만족되지 않은 경우

index.html Name: E-mail: Gender: male female

.css-form input.ng-valid.ng-touched { background-color: #78FA89; }

$scope.update = function(user) { $scope.master = angular.copy(user); };

$scope.reset = function() { $scope.user = angular.copy($scope.master); };

$scope.reset(); }]);

위의 코드는 해당폼의 값을 검증하는데 있어서 CSS를 통해 더욱 풍부하게 정보를 전달하게끔 하고 있습니다.

Binding to form and control state

form은 FormController의 인스턴스 입니다. form 인스턴스는 선택적으로 scope상의 name속성을 통해서 보이게끔 할수가 있습니다.

이와 유사하게 input의 경우에는 ngModel directive를 통해 NgModelController의 인스턴스를 가지고 있습니다. 그래서 input은 name 속성을 사용해서 input을 컨트롤할 수 가 있습니다.

코드를 통해서 더 이해를 쉽게 해보겠습니다.

index.html

Name: Tell us your name.

E-mail: Tell us your email. This is not a valid email.

Gender: male female

I agree: Please agree and sign.

app.js

angular.module('formExample', []) .controller('ExampleController', ['$scope', function($scope) { $scope.master = {};

$scope.update = function(user) { $scope.master = angular.copy(user); };

$scope.reset = function(form) { if (form) { form.$setPristine(); form.$setUntouched(); } $scope.user = angular.copy($scope.master); }; $scope.reset(); }]);

코드상의 input들의 name속성을 이용해서 폼안에서 다양한 표현들이 가능합니다. 당연히 해당 scope내에서입니다.

Custom model update triggers

ngModelOptions를 통해서 우리는 특정 행동에 우리가 원하는 기능들을 추가 할수가 있습니다.

예를들면 ng-model-options = "{updateOn : 'blur'}" 를 통해서 보통을 입력시 곧장 변경사항이 적용이 되지만 이경우에는 사용자의 포커스가 아웃이 되면 그때 변경된 내용이 적용이 됩니다.

Name: Other data: username = "{{user.name}}" userdata = "{{user.data}}"

angular.module('customTriggerExample', []) .controller('ExampleController', ['$scope', function($scope) { $scope.user = {}; }]);

Non-immediate (debounced) model updates

모델의 update/validation에 대해서 ngModelOptions의 debounce 키를 통해 딜레이를 줄수가 있습니다.

ndex.html Name: username = "{{user.name}}"

app.js angular.module('debounceExample', []) .controller('ExampleController', ['$scope', function($scope) { $scope.user = {}; }]);

조금 더 복잡하게 설정이 가능합니다.

ng-model-options="{ updateOn: 'default blur', debounce: { default: 500, blur: 0 } }"

Custom Validation

기본적으로 Angular는 대부분의 HTML5의 input타입(text, number, url, email, date, radio, checkbox)을 적용하고 있고 몇몇 directive(required, pattern, minlength, maxlength, min, max)를 통해서도 값 검증기능을 제공하고 있습니다.

물론 ngModelController의 $validators 객체를 통해서 우리가 원하는 값을 검체증하는 함수를 만들수도 있습니다. 예제를 가지고 이야기 해보도록 하갰습니다.

index.html Size (integer 0 - 10): {{size}} The value is not a valid integer! The value must be in range 0 to 10!

Username: {{name}} Checking if this name is available... This username is already taken!

app.js var app = angular.module('form-example1', []);

var INTEGER_REGEXP = /^\-?\d+$/; app.directive('integer', function() { return { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { ctrl.$validators.integer = function(modelValue, viewValue) { if (ctrl.$isEmpty(modelValue)) { // consider empty models to be valid return true; }

if (INTEGER_REGEXP.test(viewValue)) { // it is valid return true; }

// it is invalid return false; }; } }; });

app.directive('username', function($q, $timeout) { return { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { var usernames = ['Jim', 'John', 'Jill', 'Jackie'];

ctrl.$asyncValidators.username = function(modelValue, viewValue) {

if (ctrl.$isEmpty(modelValue)) { // consider empty model valid return $q.when(); }

var def = $q.defer();

$timeout(function() { // Mock a delayed response if (usernames.indexOf(modelValue) === -1) { // The username is available def.resolve(); } else { def.reject(); }

}, 2000);

return def.promise; }; } }; });

위의 예제는 integer와 username을 검증하는 directive를 만들었습니다.

우선 각각의 함수는 인자로 modelValue와 viewValue를 받았습니다. 그리고 Angular는 내부에서 $setValidity를 호출하고 함수는 (true : valid, false : invalid)식으로 값을 리턴할것입니다.

값을 검증하는 이 함수들은 input창의 값들이 변하면, 다른 말로 $setValidity가 호출이 될때마다 실행이 될것입니다. 아니면 모델이 변경되는 것을 보고 확인할수도 있습니다.

각각의 검증은 $parse와 $formatters가 성공적으로 동작을 하면 검증을 무사히 진행을 한 경우입니다. 만약에 실패를 한다믄 ngModelController.$error에 실패한 키 값이 저장이 될것입니다.

추가적으로 $asyncValidators객채가 있는데 이는 비동기적으로 값을 체크를 합니다. 아마 우리는 $http를 사용하는 시점에 매우 용이하게 사용할수가 있겠지요? 검증을 하고 promise를 통해 성공적으로 검증이 이뤄졌다면 resolved, 만약 실패를 했다면 rejected를 리턴할것입니다. 이때 우리가 검증에 필요한 키는 ngModelController.$pending에 저장을 해두고 있습니다.

Modifying build-in validators

Angular는 자체적으로 $validators를 사용하고 있으므로 우리는 손쉽게 내부적으로 이미 구현된 validators 를 대체하거나 제거할수 있습니다. 이번의 예제는 Angualr가 기본적으로 제공을 해주는 email검증 기능을 다르게 정의 해보겠습니다.

index.html Overwritten Email: This email format is invalid! Model: {{myEmail}}

app.js var app = angular.module('form-example-modify-validators', []);

app.directive('overwriteEmail', function() { var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i;

return { require: 'ngModel', restrict: '', link: function(scope, elm, attrs, ctrl) { // only apply the validator if ngModel is present and Angular has added the email validator if (ctrl && ctrl.$validators.email) {

// this will overwrite the default Angular email validator ctrl.$validators.email = function(modelValue) { return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue); }; } } }; });

오직 XXX#example.com 이라는 이름의 메일만이 우리의 검증과정에서 통과가 가능할것입니다.

Implementing custom from controls(Using ngModel)

Angular는 기본적으로 HTML기본 form(input, select, textarea)를 통한 검증으로 대부분의 경우를 효과적으로 컨트롤 하합니다. 그리고 당연히 우리가 원하는 방식으로 해당 기능의 변경도 얼마든지 가능합니다.

이번에는 우리가 ngModel과 양방향 데이터 바인딩을 이용해 새로운 입력형태를 만들어 보겠습니다.

index,html Some model = {{content}}

div[contentEditable] { cursor: pointer; background-color: #D0D0D0; }

app.js angular.module('form-example2', []).directive('contenteditable', function() { return { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { // view -> model elm.on('blur', function() { scope.$apply(function() { ctrl.$setViewValue(elm.html()); }); });

// model -> view ctrl.$render = function() { elm.html(ctrl.$viewValue); };

// load init value from DOM ctrl.$setViewValue(elm.html()); }영 }; });

사용자 지정 컨트롤러가 동작하기 위해서는 ng-model과 함께 동작을 해야하고 양방향 데이터 바인딩이 이뤄저야 합니다. 이를 위해서

$render메서드를 통해 NgModelController.$formatters 가 전달하는 데이터를 렌더링 시켜줘야합니다.

$setviewValue 메서드를 통해서 언제든지 사용자의 인터렉션을 모델에 반영시켜 줘야합니다.

좀더 자세한 내용은 https://docs.angularjs.org/guide/directive 을 통해서 확인 가능합니다.

from http://yubylab.tistory.com/74 by ccl(A) rewrite - 2020-03-06 15:20:42

댓글

이 블로그의 인기 게시물

[django] django rest framework 로그인 과정 | 장고 로그인 | 인증...

[django] django rest framework 로그인 과정 | 장고 로그인 | 인증... django 는 기능이 참 너무 많다 ^^; 지금은 서버는 django로, 프론트는 angular를 붙여서 간단한 웹을 만들어 보려고 한다. 웹 만들때 항상 회원가입/로그인 기능은 맨 앞에 구현한다. 어떻게 구현하면 좋을까... 찾아보다가 이 기능을 구현할 수 있는 방법이 너무 많아서 정보를 찾기 더 어려웠다. 일단 나는 django에서 django rest framework라는 것을 사용해서 API를 만드려고 한다. 순수 django 튜토리얼에는 바로 template 랑 연결해서 설명하는 부분이 많았다. 나는 그냥 API 만 만들고 싶다고!! 그래서 찾은 것이 django REST framework. https://www.django-rest-framework.org/api-guide/authentication django REST framework 설치 using pip pip install djangorestframework settings.py INSTALLED APPS 에 추가해야함 INSTALLED_APPS = [ ... 'rest_framework', ] django REST framework 에서도 인증 관련해서 제공하는 것이 1개가 아닌 여러 개다. 나는 그중에 TokenAuthentication을 이용해서 로그인을 구현해 보려고 한다. TokenAuthentication Token authentication is appropriate for client-server setups, such as native desktop and mobile clients. 이렇게 나와있어서 내가 하려는 것과 일치해서 이걸로 결정 ~ 솔직히 처음 로그인을 구현하려고 하면 도대체 그 과정이 어떻게 되는지 모를 수 도 있다. 나는 쉽게 정리하면 아래와 같은 과정이라고 생각한다. 로그인 로그아웃...

(주)레터플라이 채용 정보: 프로그래밍을 생각하면 가슴이 뛰는 개발자...

(주)레터플라이 채용 정보: 프로그래밍을 생각하면 가슴이 뛰는 개발자... Angular.js, Python, MySQL 중 한 가지 언어에 뛰어나신 분도 좋고 개발 업무 전반적으로 센스가 있으신 분도 환영합니다. 맡은 업무를 성실하게 수행해 나갈 수 있는 책임감과 태도를 갖고계신 분, 그리고 항상 새로운 방법론에 도전하고 포기를 모르는 분일수록 저희와 더욱 잘 맞을 것 같습니다. Angular.js, Python, MySQL 중 한 가지 언어에 뛰어나신 분도 좋고 개발 업무 전반적으로 센스가 있으신 분도 환영합니다. 팀 내 뛰어난 풀스택 개발자분들이 Angular.js, Python, MySQL 모두 작업 가능하시니 오셔서 함께 배우며 즐겁게 작업하시면 됩니다. 맡은 업무를 성실하게 수행해 나갈 수 있는 책임감과 태도를 갖고계신 분, 그리고 항상 새로운 방법론에 도전하고 포기를 모르는 분일수록 저희와 더욱 잘 맞을 것 같습니다. 개발 업무: 레터플라이의 핵심 기능인 편지, 사진을 제작하는 레터에디터, 포토에디터 개발. 이 기능들은 "모바일 웹을 통한 출력제품 생산 자동화 기술"(특허 출원 준비중)로서 레터플라이에서 자체개발했습니다. 근무 지역: 광화문역 5번출구 바로 앞 근무 환경: 책임과 존중을 중요시하는 수평적인 분위기, 도전적이며 서로에게 배우는 문화 근무 시간: 10-19시, 출근시간 자유 지정. 급여: 연봉/스톡옵션 협의 지원 방법: 팀 지원하기 더 많은 내용은 더 많은 내용은 더팀스 에서 확인하세요! from http://theteams.tistory.com/721 by ccl(A) rewrite - 2020-03-20 09:20:18

jqxGrid 정렬, 필터 메뉴 숨기기

jqxGrid 정렬, 필터 메뉴 숨기기 How I can remove filter to particular grid column - Angular, Vue, React, Web Components, Javascript, HTML5 Widgets Hi, I tried that it's working. I set properties to those columns as sortable: false, filterable: false. but when I clicked on the column one drop down is appearing with options "sort ascending", "sort descending", "remove sort" and those are all in disable www.jqwidgets.com from http://devesim.tistory.com/90 by ccl(A) rewrite - 2020-03-11 04:20:29