기본 콘텐츠로 건너뛰기

[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

댓글

이 블로그의 인기 게시물

[Angular] Router 라우터 정리

[Angular] Router 라우터 정리 Angular2 버전 이후를 기준으로 정리한 글입니다. 라우터는 URL을 사용하여 특정 영역에 어떤 뷰를 보여 줄지 결정하는 기능을 제공한다. 전통적인 서버사이드 렌더링을 하는 웹 사이트는 주소가 바뀔 때마다 서버에 전체 페이지를 요청하고 전체 페이지를 화면에 렌더링한다. 매 요청시 전체 페이지를 새로 랜더링하는 것은 비효율적이기 때문에 라우터를 이용하여 필요한 부분만 랜더링을 한다면 효율적일 것이다. 라우터는 URL에 해당하는 컴포넌트를 화면에 노출하고 네비게이션을 할 수 있는 기능을 가지고 있다. Router 구성 요소 Router – 라우터를 구현하는 객체이다. Navigate() 함수와 navigateByUrl() 함수를 사용하여 경로를 이동할 수 있다. RouterOulet – 라우터가 컴포넌트를 태그에 렌더링하는 영역을 구현하는 Directive이다. Routes – 특정 URL에 연결되는 컴포넌트를 지정하는 배열이다. RouterLink – HTML의 앵커 태그는 브라우저의 URL 주소를 변경하는 것이다. 앵귤러에서 RouterLink를 사용하면 라우터를 통해 렌더링할 컴포넌트를 변경할 수 있다. ActivatedRoute – 현재 동작하는 라우터 인스턴스 객체이다. Router 설정 라우터를 사용하기 위해서는 먼저 Router 모듈을 import 해야 한다. import { RouterModule, Routes } from '@angular/router'; 라우터에서 컴포넌트는 고유의 URL과 매칭된다. URL과 컴포넌트는 아래와 같이 Routes 객체를 설정하여 지정할 수 있다. 아래의 예에서는 디폴트 path에서는 MainComponent가 노출이 되고 product-list path에서는 ProductListComponent가 노출이 되도록 설정을 한 것을 볼 수 있다. const routes: Routes = [ { pa...

[Angular] Controller

[Angular] Controller Step02_controller.html // angular 모듈 만들기 var myApp = angular.module( "myApp" ,[]); // Ctrl1 이라는 이름의 컨트롤러 만들기 myApp.controller( "Ctrl1" ,[ "$scope" , function ($scope){ $scope. name = "김구라" ; $scope.clicked = function (){ alert ( "버튼을 눌렀네?" ); }; $scope.nums = [ 10 , 20 , 30 , 40 , 50 ]; }]); // Ctrl2 이라는 이름의 컨트롤러 만들기 myApp.controller( "Ctrl2" ,[ "$scope" , function ($scope){ $scope. name = "원숭이" ; $scope.friends = [ {num: 1 , name : "김구라" ,addr: "노량진" }, {num: 2 , name : "해골" ,addr: "행신동" }, {num: 3 , name : "원숭이" ,addr: "동물원" } ]; }]); 내이름은 : {{name}} 눌러보셈 {{tmp}} 너의 이름은 : {{name}} 번호 이름 주소 {{tmp.num}} from http://heekim0719.tistory.com/164 by ccl(A) rewrite - 2020-03-07 09:21:16

JQuery - $ 사용 유형.

JQuery - $ 사용 유형. 최근에 새로운 Javascript 프레임워크와 라이브러리들이 많이 등장했고 시장 점유율 또한 많이 변동 되었다고 한다. 특히 요새 대새는 Angular와 React라고들 한다. 그리고 Jquery 요즘 누가써? Jquery 퇴물이야 등등... 그런 이야기들을 종종 찾아볼 수 있는데, 유행은 돌고 돌듯이 결국 Jquery가 몰락할 일은 없다고 생각하는 바, 묵묵히 Jquery를 고집하기로 한다...ㅎㅎ 먼저 Jquery 교과서랄까.. 기본 문법을 배울 수 있는 링크를 걸어둔다. https://www.w3schools.com/jquery 여기서 기초들을 다 익힐 수 있다. 프로그래밍 문법을 한번이라도 봤다면 + - * / 같은 연산 while, for 등은 다 비슷하기 때문에 $ 사용법만 잘 알면 될 것 같다. $ syntax 사용유형 일단 기본적으로 $는 JQuery에서 미리 정해놓은 변수 값이다. : JQueryStatic 1. $( ) : JQueryObject 가장 많이 사용하는 형태이다. 괄호 안에 들어 갈 수 있는 것들은 클래스 이름, 아이디, 셀렉터 등이다. 예를 들어 $('p')이면 현재 html 페이지에 있는 모든 를 JqueryObject로 가져오겠다는 것이다. hide()는 제이쿼리 메서드이다. $('p')는 제이쿼리 오브젝트이기 때문에 제이쿼리 메서드를 사용할 수 있다. 그중의 하나인 hide()를 사용해 보았다. 결과이다. 에는 스타일이 적용이 되었다. 해당 태그에는 jquery의 메서드가 적용이 된 것을 확인할 수 있다. 2. $.함수 : 플러그인 개발 또는 기본 전역함수 플러그인을 개발 할 때나 Jquery가 갖고 있는 기본 전역함수들을 사용할 때 쓴다. 전역함수에는 여러개가 있는데 그중에 개인적으로 많이 쓰는 것은 $.ajax({}), $.each({}) 등이 있다. 이 함수들의 사용방법은 따...