AngularJS 튜토리얼: 사용자 지정 지시문 이해하기
게시 됨: 2022-03-11JavaScript가 풀 스택 언어로 빠르게 성장함에 따라 점점 더 많은 응용 프로그램에서 웹 브라우저가 데이터 바인딩, 데이터 보기 관리, 데이터 변환 및 기타 여러 서비스와 같은 UI 처리를 더 많이 처리할 수 있도록 하는 프레임워크를 활용하고 있습니다. 가장 유능하고 확장 가능하며 인기 있는 프레임워크 중 하나는 AngularJS이며, AngularJS 프레임워크의 가장 유용한 구성 요소 중 하나는 지시문 이라고 하는 것입니다. AngularJS는 많은 유용한 지시문을 제공하며 더욱 중요한 것은 사용자 지정 지시문을 생성하기 위한 풍부한 프레임워크를 제공한다는 것입니다.
지시문이란 무엇입니까? 간단히 말해서 지시문은 HTML DOM 요소를 조작하고 동작을 추가하는 JavaScript 함수입니다. 지시문은 매우 단순하거나 매우 복잡할 수 있습니다. 따라서 이를 조작하는 많은 옵션과 기능을 확실히 파악하는 것이 중요합니다.
이 튜토리얼에서는 지시문으로 실행되는 네 가지 기능을 생성하여 DOM에 적용하고 예제를 제공합니다. 이 게시물은 AngularJS 및 사용자 지정 지시문에 대해 어느 정도 익숙하다고 가정합니다. Angular를 처음 사용하는 경우 첫 번째 AngularJS 앱 빌드에 대한 자습서를 즐길 수 있습니다.
AngularJS 지시문 라이프 사이클의 네 가지 기능
구성할 수 있는 많은 옵션이 있으며 이러한 옵션이 서로 관련되는 방식이 중요합니다. 각 지시문은 AngularJS가 DOM을 컴파일하고 링크할 때 수명 주기와 유사한 과정을 거칩니다. 지시문 수명 주기는 페이지가 렌더링되기 전에 AngularJS 부트스트랩 프로세스 내에서 시작되고 끝납니다. 지시어의 수명 주기에는 정의된 경우 실행할 수 있는 네 가지 고유한 기능이 있습니다. 각각을 통해 개발자는 수명 주기의 여러 지점에서 지시문을 제어하고 사용자 지정할 수 있습니다.
네 가지 기능은 compile , controller , pre-link 및 post-Link 입니다.
컴파일 기능을 사용하면 지시문이 컴파일 및 링크되기 전에 DOM을 조작할 수 있으므로 지시문을 추가/제거/변경할 수 있을 뿐만 아니라 다른 DOM 요소를 추가/제거/변경할 수 있습니다.
컨트롤러 기능은 지시적 통신을 용이하게 합니다. 형제자매 및 자식 지시문은 형제자매 및 부모의 컨트롤러에 정보를 전달하도록 요청할 수 있습니다.
사전 연결 기능은 사후 연결 프로세스가 시작되기 전에 비공개 $scope 조작을 허용합니다.
사후 링크 방법은 지시문의 주요 방법입니다.
지시문에서 사후 컴파일 DOM 조작이 발생하고 이벤트 핸들러가 구성되며 시계 및 기타 사항도 구성됩니다. 디렉티브의 선언에는 이렇게 4개의 함수가 정의되어 있습니다.
.directive("directiveName",function () { return { controller: function() { // controller code here... }, compile: { // compile code here... return { pre: function() { // pre-link code here... }, post: function() { // post-link code here... } }; } } })
일반적으로 모든 기능이 필요한 것은 아닙니다. 대부분의 경우 개발자는 아래 패턴에 따라 단순히 컨트롤러 와 포스트 링크 기능을 생성합니다.
.directive("directiveName",function () { return { controller: function() { // controller code here... }, link: function() { // post-link code here... } } })
이 구성에서 링크 는 링크 후 기능을 나타냅니다.
함수의 전체 또는 일부가 정의되었는지 여부에 관계없이 실행 순서가 중요합니다. 특히 나머지 AngularJS 응용 프로그램과 관련된 실행이 중요합니다.
다른 지시문과 관련된 AngularJS 지시문 함수 실행
HTML 프래그먼트에 적용되는 parentDir , childDir 및 grandChildDir 지시문이 있는 다음 HTML 스니펫을 고려하십시오.
<div parentDir> <div childDir> <div grandChildDir> </div> </div> </div>
지시문 내에서 다른 지시문과 관련된 함수의 실행 순서는 다음과 같습니다.
- 컴파일 단계
- 컴파일 기능 : parentDir
- 컴파일 기능 : childDir
- 컴파일 기능 : grandChildDir
- 컨트롤러 및 사전 링크 단계
- 컨트롤러 기능 : parentDir
- 사전 링크 기능 : parentDir
- 컨트롤러 기능 : childDir
- 사전 링크 기능 : childDir
- 컨트롤러 기능 : grandChildDir
- 사전 링크 기능 : grandChildDir
- 링크 후 단계
- 포스트 링크 기능 : grandChildDir
- 포스트 링크 기능 : childDir
- 포스트 링크 기능 : parentDir
AngularJS 지시문 함수 설명: 심층 분석
컴파일 단계가 먼저 발생합니다. 기본적으로 컴파일 단계에서는 이벤트 리스너를 DOM 요소에 연결합니다. 예를 들어 특정 DOM 요소가 $scope 속성에 바인딩되어 있으면 $scope 속성 값으로 업데이트할 수 있는 이벤트 리스너가 DOM 요소에 적용됩니다. 컴파일 프로세스는 AngularJS 애플리케이션이 부트스트랩된 루트 DOM 요소에서 시작하고 깊이 우선 탐색을 사용하여 DOM의 분기를 탐색하여 부모를 먼저 컴파일한 다음 자식을 리프 노드까지 컴파일합니다.
컴파일이 완료되면 더 이상 DOM에서 지시문을 추가하거나 제거할 수 없습니다(컴파일 서비스를 직접 사용하여 이 문제를 해결하는 방법이 있습니다. 다음 단계는 모든 지시문에 대한 컨트롤러 및 사전 연결 기능을 호출하는 것입니다. 컨트롤러가 컨트롤러에 주입된 $ element 는 컴파일된 템플릿을 포함하지만 트랜스클루드된 자식 콘텐츠는 포함하지 않습니다(트랜스클루드된 콘텐츠는 지시문이 있는 시작 및 끝 HTML 태그 사이의 콘텐츠입니다. 적용됨). 정의에 따르면 MVC 패턴의 컨트롤러는 단순히 모델을 뷰에 전달하고 이벤트 처리를 위한 함수를 정의합니다. 따라서 지시어의 컨트롤러는 두 가지 이유로 지시문의 DOM을 수정해서는 안 됩니다. 컨트롤러, 그리고 트랜스클루드된 자식 콘텐츠는 DOM에 추가되지 않았습니다.그래서 컨트롤러는 $scope 를 수정하는 것 외에 무엇을 합니까?컨트롤러는 자식 지시문이 th 부모 지시문. 컨트롤러 기능 자체는 자식 지시문이 요청하는 경우 자식 지시문의 사후 링크 기능으로 전달되는 컨트롤러 개체로 간주해야 합니다. 따라서 컨트롤러는 일반적으로 형제 및 자식 지시문에서 사용할 수 있는 속성과 메서드가 있는 개체를 만들어 지시문 통신을 용이하게 하는 데 사용됩니다. 부모 지시문은 자식 지시문이 컨트롤러를 요구할 수 있는지 여부를 결정할 수 없으므로 이 메서드의 코드를 자식 지시문에서 안전하게 사용할 수 있는 기능과 속성으로 제한하는 것이 가장 좋습니다.

컨트롤러 기능 이후에 프리링크 기능이 실행됩니다. 사전 링크 기능은 많은 사람들에게 신비합니다. 인터넷과 책에서 많은 문서를 읽으면 사람들은 이 기능이 드문 경우에만 사용되며 사람들이 거의 필요로 하지 않을 것이라고 씁니다. 그런 다음 동일한 설명이 사용될 수 있는 상황의 예를 제공하지 못합니다.
사전 연결 기능은 실제로 전혀 복잡하지 않습니다. 먼저 AngularJS 소스 코드를 검토하면 사전 연결 기능의 훌륭한 예를 찾을 수 있습니다. ng-init 지시문이 이를 사용합니다. 왜요? $scope 를 포함하는 개인 코드를 실행하는 훌륭한 방법입니다. 형제 및 자식 지시문에서 호출할 수 없는 코드입니다. 컨트롤러 기능과 달리 사전 연결 기능은 지시문으로 전달되지 않습니다. 따라서 지시문의 $scope 를 수정하는 코드를 실행하는 데 사용할 수 있습니다. 지시문 ng-init 이 정확히 이 작업을 수행합니다. ng-init 에 대한 사전 링크 기능이 실행될 때 지시문에 전달된 JavaScript를 지시문의 $scope 에 대해 실행하기만 하면 됩니다. 실행 결과는 $scope 의 프로토타입 상속을 통해 컨트롤러, 링크 전 및 링크 후 함수 실행 중에 자식 지시문에 사용할 수 있지만 부모의 사전에 있는 코드를 다시 실행하기 위해 해당 자식 지시문에 액세스할 수 없습니다. 링크 기능. 또한 지시문은 비공개로 유지하려는 $scope 와 관련이 없는 다른 코드를 실행해야 할 수도 있습니다.
경험 많은 AngularJS 개발자 중 일부는 이 개인 코드를 컨트롤러에 배치한 다음 자식 지시문에서 호출하지 않을 수 있다고 말합니다. 지시문을 코딩한 원래 개발자만 지시문을 사용할 경우 해당 인수는 유효하지만 지시문이 다른 개발자에 의해 배포되고 재사용될 경우 사전 링크 기능에 개인 코드를 캡슐화하는 것이 매우 유용할 수 있습니다. 개발자는 자신의 지시문이 시간이 지남에 따라 어떻게 재사용될지 결코 알지 못하기 때문에 개인 코드가 자식 지시문에 의해 실행되지 않도록 보호하는 것은 지시문 코드 캡슐화에 대한 좋은 접근 방식입니다. 지시적 통신 공개 코드를 컨트롤러 기능에 배치하고 개인 코드를 사전 링크 기능에 배치하는 것이 좋습니다. 컨트롤러와 마찬가지로 사전 링크는 DOM 조작을 수행하거나 자식 지시문에 대한 내용이 아직 링크되지 않았기 때문에 transclude 기능을 실행해서는 안됩니다.
각 지시문에 대해 컨트롤러 및 사전 연결 기능은 하위 지시문의 컨트롤러 및 사전 연결 기능보다 먼저 실행됩니다. 모든 지시문에 대한 컨트롤러 및 사전 연결 단계가 완료되면 AngularJS는 연결 단계를 시작하고 각 지시문에 대한 사후 연결 기능을 실행합니다. 연결 단계는 리프 DOM 노드에서 시작하여 루트 DOM 노드까지 작업하여 컴파일, 컨트롤러 및 사전 연결 실행 흐름과 반대로 실행됩니다. 링크 후 DOM 탐색은 대부분 깊이 우선 경로를 따릅니다. 각각의 자식 지시문이 링크되면 링크 후 기능이 실행됩니다.
링크 후 기능은 사용자 정의 AngularJS 지시문에서 가장 일반적으로 구현되는 기능입니다. 이 기능에서는 거의 모든 합리적인 작업을 수행할 수 있습니다. DOM을 조작할 수 있고(자체 및 자식 요소에 대해서만), $scope 를 사용할 수 있으며, 부모 지시문에 대한 컨트롤러 개체를 사용할 수 있고, transclude 기능을 실행할 수 있습니다. 그러나 몇 가지 제한 사항이 있습니다. 새 지시문은 컴파일되지 않으므로 DOM에 추가할 수 없습니다. 또한 모든 DOM 조작은 DOM 함수를 사용하여 수행해야 합니다. 단순히 DOM 요소에서 html 함수를 호출하고 새 HTML을 전달하면 컴파일 프로세스 중에 추가된 모든 이벤트 핸들러가 제거됩니다. 예를 들어 다음은 예상대로 작동하지 않습니다.
element.html(element.html());
또는
element.html(element.html() + "<div>new content</div>");
코드로 인해 HTML이 변경되지는 않지만 DOM 요소의 문자열 버전을 재할당하면 컴파일 프로세스 중에 생성된 모든 이벤트 핸들러가 제거됩니다. 일반적으로 사후 링크 기능은 이벤트 핸들러인 $watch 및 $observe 를 연결하는 데 사용됩니다.
모든 포스트 링크 기능이 실행되면 $scope 가 컴파일되고 링크된 DOM 구조에 적용되고 AngularJS 페이지가 활성화됩니다.
지시어 기능 차트
다음은 각 기능의 목적, 실행 시 사용할 수 있는 항목 및 각 기능을 적절하게 사용하는 방법에 대한 모범 사례를 나열한 차트입니다.
실행 주문하다 | 지령 함수 | DOM | 트랜스클루드 | $스코프 | 호출 가능 어린이 기준 |
---|---|---|---|---|---|
1 | 엮다 | DOM이 컴파일되지 않았지만 템플릿이 DOM 요소 콘텐츠 영역에 로드되었습니다. 지시문을 추가 및 제거할 수 있습니다. DOM은 DOM 함수와 HTML 문자열 교체로 조작할 수 있습니다. | Transclude 함수를 사용할 수 있지만 더 이상 사용되지 않으며 호출해서는 안 됩니다. | 사용할 수 없습니다. | 함수는 자식 요소에서 호출할 수 없습니다. |
2 | 제어 장치 | 컴파일된 DOM 요소를 사용할 수 있지만 수정해서는 안 됩니다. 트랜스클루드된 자식 콘텐츠가 DOM 요소에 추가되지 않았습니다. 이것은 컨트롤러이고 트랜스클루드된 자식 콘텐츠가 아직 연결되지 않았기 때문에 DOM 변경이 발생해서는 안 됩니다. | Transclude 함수를 사용할 수 있지만 호출해서는 안 됩니다. | $scope 를 사용할 수 있으며 사용할 수 있습니다. 함수 매개변수는 $injector 서비스를 사용하여 주입됩니다. | 함수는 함수를 연결하는 자식 지시문으로 전달되고 함수에서 호출할 수 있습니다. |
삼 | 사전 링크 | 컴파일된 DOM 요소를 사용할 수 있지만 자식 지시문 DOM 요소가 아직 연결되지 않았기 때문에 수정해서는 안 됩니다. | Transclude 함수를 사용할 수 있지만 호출해서는 안 됩니다. | $scope 를 사용할 수 있으며 수정할 수 있습니다. | 함수는 자식 지시문으로 호출할 수 없습니다. 그러나 부모 지시문의 컨트롤러를 호출할 수 있습니다. |
4 | 포스트 링크 | 컴파일된 DOM 요소와 자식 지시문 DOM 요소를 사용할 수 있습니다. DOM은 DOM 기능으로만 수정할 수 있으며(HTML 대체 없음) 컴파일이 필요하지 않은 콘텐츠만 추가할 수 있습니다. 지시문 추가/제거는 허용되지 않습니다. | Transclude 기능을 사용할 수 있으며 호출할 수 있습니다. | $scope 를 사용할 수 있으며 사용할 수 있습니다. | 지시문 자식은 호출할 수 없지만 상위 지시문의 컨트롤러를 호출할 수 있습니다. |
요약
AngularJS 지시문에 대한 이 자습서에서는 compile , controller , pre-link 및 post-link 의 4가지 지시문 기능 각각에 대한 목적, 실행 순서 및 전체 기능과 용도에 대해 배웠습니다. 네 가지 기능 중 컨트롤러와 사후 링크가 가장 일반적으로 사용되지만 DOM을 더 많이 제어해야 하거나 개인 범위 실행 환경이 필요한 더 복잡한 지시문에는 컴파일 및 사전 링크 기능을 사용할 수 있습니다.