Angular入門 未経験から1ヶ月でサービス作れるようにする その6. ngModelを使ったフォーム - Qiita
前回は、 ES6とTypescriptの基礎 Typescriptの型定義について Angularでのデータ管理の基礎2 サービスクラスの作成 を学びました。 本記事では、 HTMLのフォーム要素とTyp...
qiita.com
[(ngModel)]
Typescript와 HTML로의 쌍방향 바인딩으로 데이터가 동기화 되는 구조
https://angular.io/guide/architecture-components#data-binding
Angular
angular.io
product edit page 작성
1. ng g component product/product-edit로 컴포넌트 생성
2. routes에 추가
3. html, css 작성
4. [(ngModel)] 을 이용하여 데이터 반영
편집화면에서는 데이터를 API로 가져와서 그 데이터를 편집하고 싶은 경우가 많음.
이 경우 화면을 처음 열었을 때 API에서 취득한 데이터가 들어가는 것이 바람직함.
또한, 이 때 브라우저상에서 사용자가 편집한 데이터를 그대로 API로 등록하는 경우도 많음.
이런 경우는 Typescript <-> HTML 양방향 바인드가 적합함.
4-1. product-edit.component.ts 작성
4-2. .html 작성
Form안에서 이용하는 ngModel은 실은 name속성을 지정하지않으면 에러가 남.
Can't bind to 'ngModel' since it isn't a known property of 'input'.
때문에, 각 input요소에 name속성을 추가한 상태임.
여기서 다시 재기동해보자.
chrome의 디밸로퍼 툴(단축키 F12)을 실행하여 에러를 확인해보자.
Angular에서는 모듈(app.module.ts)에 등록되어 있지 않은 기능은 Angular의 프로젝트에 인식되지 않기때문에 이용할 수 없음. JS에 불필요한 데이터를 넣지않고 가볍게 하기위한 것이라고 생각됨.
위 에러는 향후 자주 보게되므로 대응법을 기억해두자.
Angular의 표준기능을 이용하고있으므로 공식사이트에서 ngModel을 검색해보자.
NgModel: FormsModule이라고 써있음.
이것은 ngModel은 FormsModule에 소속되어 있다는 의미임.
어떤 클래스가 어떤 모듈에 소속되어있는지 기억해두자.
아무튼
4-3. app.modules.ts에 FormsModule을 추가한다.
재실행해보면 input에 값이 반영되어 있음.
Click event로 저장 처리하기
클릭등의 HTML요소에 어떤 액션을 일으킬 때 이벤트는 HTML -> Typescript의 방향으로 바인딩됨.
그렇기때문에 ( )로 싸는 것으로 구현 됨. (반대로 Typescript->HTML 바인드는 [ ]로 둘러쌈.)
클릭이나 스크롤등의 자바스크립트가 표준으로 제공하는 이벤트들은 Angular가 처음부터 준비해주고 있음.
클릭이벤트는 (click)으로 정의되어 있음.
1. html에 클릭이벤트 추가
2. ts에 router, saveProduct()메소드 작성
저장버튼을 클릭하면 saveProduct()가 처리되고 상품 일람 페이지로 이동하도록 한다.
- Router라는 것은Angular내에서의 route의 이동이나 현재의 route정보를 가지고 있는 클래스임.
- Router는 view 사이의 navigation을 위한 매커니즘임.
- Routes는 사용자가 리크를 클릭하거나 URL을 브라우저 표시 줄에 붙여넣을 때, 표시할 view를 라우터에 알림.
- navigate메소드는 HTML상에 기재된 [routerLink]와 비슷하게 움직이고, 28행의 코드를 통해 localhost:4200/products로 화면이동시키는 것이 가능함.
- 원래는 이 메서드로 편집을 위한 API를 호출해야하는데 이번에는 양방향 바인드로 인해 메모리상의 저장은 이미 끝난 상태이기 때문에 저장처리는 실행하지않음.
양방향 바인딩의 함정
HTML로 입력한것이 그대로 Typescript상의 변수 값에 반영이 됨.
이 경우 취소버튼이 있다면 이번 경우는 이전 product의 상태를 저장하고 있지 않기때문에 원래대로 되돌릴 수 없음.
이렇게 양방향 바인딩을 사용하면 예기치못한 작동을 할 수도 있기때문에 주의가 필요함.
이를 피하기 위해 Form에서 이용하는 데이터는 새로운 요소를 준비해서 이용하는, 애초에 양방향 바인딩을 사용하지 않는 방법을 쓰는것이 좋다고 생각됨.
클릭이벤트 추가Tip
예를들어 스크롤 이벤트에서 스크롤 위치를 얻고싶은 경우와 같이 클릭 이벤트에서 이벤트 정보를 이용하고 싶을 때가 있음.
이런 경우 (click)="saveProduct($event) 와 같이 기술함.
ts쪽 정의를 saveProduct(event: MouseEvent): void 로 하면 이 인수의 event에 값이 들어감.
타입을 모를경우에는 일단 any로 정의하고 실제 작동시켜본 후에 type을 알아보면 좋음.
ngSubmit으로 Form 제한
클릭이벤트 위의 방법으로는 사실 Form을 이용하지않음. 이 경우 예를들어 Input요소에서 Enter를 누르면 자동으로 폼을 전송하는 등의 혜택을 받을수 없음.
이 지점에서 Form의 submit 이벤트를 Angular로 보완하고 Typescript의 메소드를 호출하도록 개조하기위해 등장한 것이 ngSubmit임.
ngSubmit은 form요소를 가질수 있는 디렉티브이기때문에 form요소에 추가해보겠음. html만 수정하면 됨.
저장버튼을 div로 감싼 button요소로하고 form태그의 안으로 이동시킴. (click이벤트를 멈춤. button으로 변경했으므로 클릭하면 자동적으로 form을 전송하려고 함.) 또, 이 영향으로 스타일이 흐트러지지않도록 form에 div요소를 추가함.
동작확인을 해보자.
input안에 enter를 누른것만으로도 Form이 반응하여 saveProduct()가 작동하고 /products로 화면이 바뀜.
submit vs. ngSubmit
사실 Angular에는 submit라는 것도 있음.
ngSubmit은 메서드 내부에서 throw하면 form의송신을 정지시켜주는 등의 차이가 있으므로 ngSubmit을 이용하는 것이 좋음.
'FE > Angular' 카테고리의 다른 글
データバインディング (0) | 2022.01.27 |
---|---|
7. URL 파라미터 이용 (1) | 2022.01.27 |
5. Typescript Basic, Service class (0) | 2022.01.26 |
compile error/intall node-sass/@angular-devkit (0) | 2022.01.25 |
4. Angularでのデータ管理の基礎 Directive (0) | 2022.01.25 |
댓글