AngularJS 사용자 정의 디렉티브: 템플릿, 스코프 및 트랜스클루드

⚡ 스마트 요약

AngularJS의 사용자 정의 디렉티브는 사용자가 직접 정의한 재사용 가능한 동작으로 HTML을 확장합니다. 디렉티브 팩토리는 정의 객체를 반환하며, AngularJS는 마크업에서 일치하는 요소, 속성, 클래스 또는 주석이 나타나는 모든 위치에 해당 동작을 추가합니다.

  • 🏗️ 기재: module.directive 메서드는 정규화된 이름과 디렉티브 정의 객체를 반환하는 팩토리 함수를 인수로 받습니다.
  • 🔤 명명: 이름은 내부적으로 카멜케이스 형식입니다. JavaHTML 내부의 스크립트 및 케밥 케이스, 따라서 ngGuru 페이지에는 ng-guru라고 쓰여 있습니다.
  • 🎯 어울리는: restrict 속성은 AngularJS가 요소, 속성, 클래스 또는 주석과 일치하는지 여부를 결정하며 기본값은 EA입니다.
  • 🧬 범위 접근: 지시문은 기본적으로 상위 스코프를 공유하는 반면, 스코프 옵션은 @, =, & 또는 < 바인딩을 사용하여 격리된 스코프를 생성합니다.
  • 🔗 링크 기능: 링크 함수는 스코프, 요소 및 속성을 매개변수로 받으며, DOM 리스너 및 정리 작업을 위한 적절한 위치입니다.
  • 🧱 구성 : 디렉티브는 서로 중첩될 수 있고, 트랜스클루전을 통해 임의의 마크업을 래핑할 수 있으며, 컨트롤러를 통해 형제 디렉티브에 API를 노출할 수 있습니다.
  • ⚠️ 지원 상태: AngularJS는 2021년 12월 31일부로 지원이 종료되었으며, 더 이상 패치나 보안 수정이 제공되지 않습니다.

AngularJS의 사용자 정의 디렉티브

AngularJS에서 사용자 정의 디렉티브란 무엇인가요?

A 사용자 정의 지시문 AngularJS에서 `<script>`는 사용자가 직접 작성한 동작으로 HTML을 확장하는 사용자 정의 디렉티브입니다. `<script>`는 `<script>` 태그에 등록됩니다. 모듈 AngularJS는 "디렉티브" 함수를 사용하여 페이지에서 일치하는 요소 또는 속성이 나타나는 모든 위치에 디렉티브를 적용합니다. AngularJS는 매우 강력한 기능을 많이 가지고 있습니다. 내장 지시문 예를 들어, 틀에서 벗어난 ng-반복때로는 사용자 지정 지침이 필요합니다.

⚠️ 보정: 원래 설명에는 사용자 지정 지시문이 "사용된 요소를 대체한다"고 되어 있지만, 기본적으로는 그렇지 않습니다. template 삽입 내부 일치하는 요소. 교체 필요 replace: trueAngularJS 1.3 버전부터 더 이상 사용되지 않습니다.

⚠️ 지원 관련 공지: AngularJS가 도달했습니다 2021년 12월 31일부로 생산 종료 더 이상 패치나 보안 수정이 제공되지 않습니다. 아래 내용은 기존 AngularJS 1.x 코드 유지 관리를 위해 그대로 유지되며, 최신 Angular에서는 컴포넌트와 속성 디렉티브가 이에 해당합니다.

사용자 정의 디렉티브를 사용하는 이유는 반복 때문입니다. 동일한 마크업이나 DOM 구조가 여러 화면에 나타날 때, 디렉티브는 이를 하나의 명명된 태그로 변환합니다.

사용자 정의 지시문을 만드는 방법은 무엇입니까?

AngularJS 사용자 지정 디렉티브를 만드는 방법을 예시를 통해 살펴보겠습니다.

이 경우 사용자 정의 디렉티브는 해당 디렉티브가 호출될 때 페이지에 "Angular JS 튜토리얼"이라는 텍스트가 포함된 div 태그를 삽입하는 역할을 합니다.

아래 주석이 달린 스크린샷은 그 뒤에 설명될 목록의 네 부분을 번호로 표시하고 있습니다.

사용자 정의 지시어 생성

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <div ng-guru=""></div>

</div>

<script type="text/javascript">
    var app = angular.module('DemoApp',[]);
    app.directive('ngGuru',function(){

    return {
        template: '<div>Angular JS Tutorial</div>'
    }
    });

</script>

</body>
</html>

⚠️ 경고 - 본 상품 목록에는 결함이 그대로 남아 있습니다. 해당 코드는 게시된 그대로 재현되었습니다. 여기 나열된 모든 코드에서 세 가지 오류가 반복적으로 나타납니다. chrset="UTF 8" 되어야 charset="UTF-8"; angular.js angular.min.js 둘 다 로드되므로 AngularJS가 두 번 로드됩니다. angular-route.js 의존하는 파일보다 먼저 로드됩니다.

Code 설명

  1. 우리는 먼저 모듈 AngularJS 애플리케이션에 필요합니다. 이 모듈을 사용하여 디렉티브를 생성하기 때문입니다.
  2. 저희는 현재 "ng"라는 이름의 사용자 지정 디렉티브를 만들고 있습니다.Guru"그리고 우리 지시문에 대한 사용자 지정 코드를 저장할 팩토리 함수를 정의합니다.
  3. AngularJS에서 사용자 정의 디렉티브를 위해 정의된 매개변수인 `template` 매개변수를 사용하고 있습니다. 이 매개변수를 통해 해당 디렉티브가 사용될 때마다 `template` 값을 가져와 호출 코드에 주입하도록 정의합니다.
  4. 여기서는 우리가 직접 만든 "ng-guru" 디렉티브를 사용하고 있습니다. 이렇게 하면 템플릿에 대해 정의한 값이 적용됩니다. <div>Angular JS Tutorial</div>이제 여기에 주입될 것입니다.

지시어 명명 및 정규화

이름 불일치 Java스크립트와 HTML은 대부분의 초보자에게 혼란을 줍니다. AngularJS 정규화합니다 일치시키기 전에 모든 요소와 속성 이름을 제거합니다. x- or data- 접두사를 사용하여 이름을 구분한 다음, 접두사로 구분된 이름을 변환합니다. -, : or _ camelCase로 변환합니다. 그래서 그렇습니다. ngGuru 성냥 ng-guru, 그리고 왜 data-ng-guru 이것도 잘 작동합니다. camelCase 형식이 실제 이름이고, kebab-case는 HTML에서 표기하는 방식일 뿐입니다.

⚠️ 보정: 원문에는 사용자 정의 지시문 이름이 "'ng'로 시작해야 한다"고 명시되어 있었습니다. AngularJS 공식 문서 정반대의 조언을 합니다. 자신의 지시사항 앞에 절대로 접두사를 붙이지 마십시오. ng또는 향후 내장 함수와 충돌할 수 있습니다. 다음과 같은 사용자 지정 접두사를 사용하십시오. g99Guru 로 쓰여진 g99-guru.

코드가 성공적으로 실행되면 다음과 같은 출력이 나타납니다.

출력:

사용자 정의 지시어 생성

출력 결과를 보면 사용자 정의 텍스트를 표시하기 위한 템플릿이 정의된 사용자 정의 ng-guru 디렉티브가 브라우저에 제대로 표시되는 것을 확인할 수 있습니다. 다음 단계는 해당 템플릿 안에 재사용할 만한 가치 있는 내용을 넣는 것입니다.

재사용 가능한 디렉티브를 만드는 방법

우리는 이미 사용자 정의 지시문의 힘을 보았지만 재사용 가능한 지시문을 자체적으로 구축하여 이를 다음 단계로 끌어올릴 수 있습니다.

예를 들어, 여러 화면에서 항상 아래와 같은 HTML 태그를 표시하는 코드를 삽입하고 싶다고 가정해 보겠습니다. 이 태그는 기본적으로 사용자의 "이름"과 "나이"를 입력하는 필드입니다.

재사용 가능한 지시어 생성

이 코드를 매번 다시 작성하지 않고 여러 화면에서 이 조각을 재사용하려면 AngularJS에서 이 두 컨트롤을 담는 마스터 컨트롤 또는 디렉티브를 만듭니다.

이제 모든 화면에서 해당 마크업을 반복하는 대신, 디렉티브에 포함시키고 해당 디렉티브를 호출합니다. 아래 스크린샷은 변경되는 유일한 줄을 보여줍니다.

재사용 가능한 지시어 생성

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <div ng-guru=""></div>

</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.directive('ngGuru',function(){
        return {

            template: '&nbsp;&nbsp;Name <input type="text"><br><br>&nbsp;&nbsp;&nbsp;Age<input type="text">'
        };
    });

</script>

</body>
</html>

Code 설명

  • 사용자 정의 지시문 코드 스니펫에서 변경되는 부분은 템플릿 매개변수에 전달되는 값뿐입니다. 일반 태그나 텍스트 한 줄 대신, 페이지에 표시해야 하는 "이름"과 "나이" 두 입력란의 전체 내용을 입력합니다.

💡 Tip 이렇게 긴 템플릿은 별도의 파일에 있어야 합니다. template 을 통한 templateUrl: 'name-age.html'.

코드가 성공적으로 실행되면 다음과 같은 출력이 나타납니다.

출력:

재사용 가능한 지시어 생성

위 출력에서 ​​볼 수 있듯이, 사용자 정의 지시문의 템플릿에 있는 코드 조각이 페이지에 추가되었습니다. 템플릿은 아직 정적이므로 다음 단계는 데이터를 입력하는 것입니다.

AngularJS 디렉티브 및 스코프

The 범위 컨트롤러와 뷰를 연결하는 접착제 역할을 하며, 뷰와 컨트롤러 간의 데이터를 관리하는 것으로 정의됩니다.

AngularJS에서 사용자 정의 디렉티브를 생성할 때, 기본적으로 상위 컨트롤러의 스코프 객체에 접근할 수 있습니다. 이는 복사본이 아닌 동일한 스코프 객체입니다.

이러한 방식으로 사용자 지정 지시문이 메인 컨트롤러에 전달되는 데이터를 활용하는 것이 쉬워집니다.

부모 컨트롤러의 스코프를 사용자 정의 디렉티브에서 사용하는 방법을 예시를 통해 살펴보겠습니다. 아래 스크린샷은 네 단계를 번호로 표시한 것입니다.

AngularJS 디렉티브 및 스코프

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoController">
    <div ng-guru=""></div>

</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.controller('DemoController',function($scope) {
        $scope.tutorialName = "Angular JS";

    });

        app.directive('ngGuru',function(){
        return {
         template: '<div>{{tutorialName}}</div>'
     }
    });

</script>

</body>
</html>

Code 설명

  1. 먼저 "DemoController"라는 컨트롤러를 생성합니다. 이 컨트롤러에서 tutorialName이라는 변수를 정의하고, 한 문장으로 스코프 객체에 연결합니다. $scope.tutorialName = "Angular JS".
  2. 사용자 정의 지시문에서 표현식을 사용하여 "tutorialName" 변수를 호출할 수 있습니다. 이 변수는 이 지시문의 상위가 되는 컨트롤러 "DemoController"에 정의되어 있으므로 액세스할 수 있습니다.
  3. 상위 div 태그 역할을 하는 div 태그에서 컨트롤러를 참조합니다. 사용자 정의 지시문이 tutorialName 변수에 액세스하려면 이 작업을 먼저 수행해야 합니다.
  4. 마지막으로 사용자 정의 지시문 “ng-guru”를 div 태그에 연결합니다.

코드가 성공적으로 실행되면 다음과 같은 출력이 나타납니다.

출력:

AngularJS 디렉티브 및 스코프

위 출력 결과는 사용자 정의 디렉티브 "ng-guru"가 상위 컨트롤러의 스코프 변수 tutorialName을 사용하고 있음을 명확히 보여줍니다. 상위 컨트롤러의 스코프를 공유하는 것은 편리하지만, 항상 바람직한 것은 아닙니다.

지시어와 함께 컨트롤러 사용

AngularJS는 다음과 같은 기능을 제공합니다. 사용자 정의 지시문에서 직접 컨트롤러의 멤버 변수에 액세스 범위 개체가 필요하지 않습니다.

이는 애플리케이션이 여러 컨트롤러에 속하는 여러 스코프 객체를 가질 수 있기 때문에, 실수로 잘못된 컨트롤러의 스코프 객체에 접근할 가능성이 높으므로 때때로 필요해집니다.

이러한 시나리오에서는 디렉티브에서 "이 컨트롤러에 접근하고 싶다"라고 명확하게 지정하는 방법이 있습니다.

이를 달성하는 방법을 예시를 통해 살펴보겠습니다. 스크린샷에는 네 단계가 번호로 표시되어 있습니다.

지시어와 함께 컨트롤러 사용

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoController">
    <div ng-guru99=""></div>

</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.controller('DemoController',function() {
        this.tutorialName = "Angular";

    });

     app.directive('ngGuru99',function(){
        return {
         controller: 'DemoController',

          controllerAs: 'ctrl',

          template: '{{ctrl.tutorialName}}'
     };
    });

</script>

</body>
</html>

Code 설명

  1. 먼저 "DemoController"라는 컨트롤러를 생성합니다. 이 컨트롤러에서 "tutorialName"이라는 변수를 정의하는데, 이번에는 스코프 객체에 연결하는 대신 컨트롤러에 직접 연결합니다.
  2. 사용자 정의 지시문에서는 컨트롤러 매개변수 키워드를 사용하여 컨트롤러 "DemoController"를 사용하고 싶다고 구체적으로 언급하고 있습니다.
  3. AngularJS에서 정의한 "controllerAs" 매개변수를 사용하여 컨트롤러에 대한 참조를 생성합니다. 이는 별칭을 통해 컨트롤러를 참조하는 방법입니다.
  4. 마지막으로, 템플릿에서는 3단계에서 생성한 참조와 1단계에서 컨트롤러에 직접 연결한 멤버 변수를 사용합니다.

참고 : 디렉티브에서 여러 컨트롤러에 접근하려면 컨트롤러, controllerAs 및 템플릿 문에 해당하는 블록을 지정하면 됩니다. 부모의 지시문의 컨트롤러 대신 사용하세요. require.

코드가 성공적으로 실행되면 다음과 같은 출력이 나타납니다.

출력:

지시어와 함께 컨트롤러 사용

출력 결과는 사용자 정의 디렉티브가 DemoController와 그에 연결된 멤버 변수 tutorialName에 접근하여 "Angular"라는 텍스트를 표시하는 것을 명확히 보여줍니다. 두 접근 방식 모두 공유 스코프에서 읽어오는데, 격리 스코프를 사용하면 이러한 문제를 방지할 수 있습니다.

격리된 스코프에서 @, =, &, < 바인딩의 차이점은 무엇인가요?

부모 스코프를 공유하는 디렉티브는 컨트롤러당 한 번만 사용할 수 있습니다. 두 개의 복사본이 동일한 변수를 두고 충돌하기 때문입니다. scope 객체가 생성합니다 격리 범위지시문은 사용자가 나열한 속성 외에는 외부의 어떤 것도 인식하지 못합니다. 각 항목은 접두사 기호를 사용하여 값이 전달되는 방식을 나타냅니다.

상징 방향 받은 값 그것을 위해 그것을 사용하십시오
@ 일방통행 속성은 보간된 문자열로 표시됩니다. 레이블, 제목, 기타 일반 텍스트
= 양방향 살아있는 객체 또는 가치 그 자체 모델은 지시사항에 대한 응답을 작성합니다.
& 외부 호출 외부 스코프의 표현식을 평가하는 함수 닫기 또는 저장과 같은 콜백
< 일방통행 평가된 값은 절대 상향 조정되지 않습니다. AngularJS 1.5에서 추가된 읽기 전용 데이터입니다.

💡 Tip 도달 < 전에 =단방향 바인딩은 모니터링 비용이 저렴하고 컴포넌트가 호출자의 데이터를 조용히 변경하는 것을 방지합니다. 다음 섹션에서는 이를 사용합니다. @.

AngularJS 디렉티브 및 컴포넌트: ng-transclude

앞서 언급했듯이 AngularJS는 기능을 확장하기 위해 만들어졌습니다. HTML. 그리고 우리는 재사용 가능한 사용자 지정 지시문을 사용하여 코드를 삽입하는 방법을 이미 살펴보았습니다.

하지만 현대 웹 애플리케이션 개발에는 개발이라는 개념도 있습니다.ping 웹 컴포넌트란 기본적으로 코드에서 컴포넌트로 사용할 수 있는 자체 HTML 태그를 만드는 것을 의미합니다.

따라서 AngularJS는 호출자가 태그 안에 넣는 모든 마크업을 태그로 감쌀 수 있는 기능을 제공함으로써 HTML 태그를 확장하는 데 있어 또 다른 차원의 강력한 기능을 제공합니다.

이는 “ng-transclude이 지시문은 AngularJS에게 마크업의 사용자 정의 태그 안에 있는 모든 것을 캡처하여 해당 위치에 템플릿에 삽입하도록 지시합니다.

이를 달성하는 방법을 예를 들어 보겠습니다. 아래 스크린샷에는 다섯 가지 항목이 번호로 표시되어 있습니다.

AngularJS 지시문 및 구성 요소

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <pane title="{{title}}">Angular JS</pane>

</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.directive('pane',function(){
        return {

            transclude:true,
            scope :{title:'@'},
            template: '<div style="border: 1px solid black;"> '+
                        '<ng-transclude></ng-transclude>'+
                            '</div>'
        };
    });

</script>

</body>
</html>

Code 설명

  1. 우리는 디렉티브를 사용하여 "pane"이라는 사용자 지정 HTML 태그를 정의하고, 팩토리 함수를 통해 해당 태그의 코드를 제공합니다. 출력에서 ​​pane 태그는 검은색 실선 테두리가 있는 사각형 안에 "Angular JS"라는 텍스트를 표시합니다.
  2. "transclude" 속성을 true로 설정해야 합니다. 이렇게 하면 AngularJS가 원래 내부 마크업을 유지하고 사용할 수 있도록 합니다. ng-transclude.
  3. 스코프 객체에서 제목 바인딩을 선언합니다. 속성은 일반적으로 이름/값 쌍으로 작성됩니다. name="value"우리 경우에는 pane 태그의 속성이 "title"이고, "@" 기호는 AngularJS에게 해당 속성을 보간된 문자열로 복사하도록 요청합니다.
  4. 템플릿은 컨트롤에 검은색 실선 테두리를 그리고, 포함된 마크업이 삽입될 위치를 표시합니다.
  5. 마지막으로, 정의해둔 title 속성과 함께 사용자 지정 HTML 태그를 호출합니다.

⚠️ 보정: 원문에서는 "@"를 "Angular에서 요구하는 사항"이라고 설명했습니다. 이는 형식적인 절차가 아닙니다. @ 위 표에 있는 네 가지 격리 범위 바인딩 기호 중 하나이며 항상 문자열을 반환합니다. 이 템플릿은 또한 렌더링되지 않습니다. {{title}}그리고 어떤 컨트롤러도 정의하지 않습니다 title따라서 포함된 텍스트만 표시됩니다.

코드가 성공적으로 실행되면 다음과 같은 출력이 나타납니다.

출력:

AngularJS 지시문 및 구성 요소

  • 출력 결과는 사용자 지정 패널 요소가 테두리가 있는 상자 형태로 렌더링되고 그 안에 "Angular JS"라는 텍스트가 포함된 것을 보여줍니다.

지시문은 다른 지시문을 포함할 수도 있으며, 이것이 더 큰 구성 요소들을 조립하는 방식입니다.

중첩된 지시문

AngularJS의 디렉티브는 중첩될 수 있습니다. 마치 어떤 모듈이나 함수 안에도 디렉티브를 넣는 것과 같습니다. 프로그래밍 언어, 서로 지시문을 포함해야 할 수도 있습니다.

아래 예를 보면 이에 대해 더 잘 이해할 수 있습니다.

이 예에서는 "outer" 및 "inner"라는 2개의 지시어를 생성합니다.

  • inner 지시문은 "Inner"라는 텍스트를 표시합니다.
  • 외부 지시문은 실제로 내부 지시문을 호출하여 "Inner"라는 텍스트를 표시합니다.

아래 스크린샷은 두 지시문 정의와 하나가 다른 하나를 호출하는 지점을 표시합니다.

중첩된 지시어

</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <outer></outer>
</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.directive('outer',function(){
        return {

            restrict:'E',
            template: '<div><h1>Outer</h1><inner></inner></div>',
        }});

    app.directive('inner',function(){
        return {

            restrict:'E',
            template: '<div><h1>Inner</h1></div>',
        }
    });
</script>

</body>
</html>

⚠️ 경고 - 결함이 이 목록에 그대로 남아 있습니다. 공개된 목록은 다음에서 시작됩니다. </head>개막을 놓쳤습니다. <!DOCTYPE html>, <html> <head> 이 줄들을 실행하기 전에 추가하세요.

Code 설명

  1. 우리는 부모 지시문처럼 작동할 "outer"라는 지시문을 만들고 있습니다. 그런 다음 이 지시문은 “inner” 지시문을 호출합니다.
  2. The restrict:'E' 이 옵션은 AngularJS에게 각 디렉티브를 일치시키도록 지시합니다. 요소 이름 때문에 태그로 표기될 수 있는 것입니다. <outer> <inner>'E'는 'Element'라는 단어의 줄임말입니다.
  3. 여기서는 div 태그에 "Inner"라는 텍스트를 표시하는 inner 지시문을 만듭니다.
  4. 외부 디렉티브의 템플릿에서 내부 디렉티브를 호출하고 있습니다. 즉, 여기서는 내부 디렉티브의 템플릿을 외부 디렉티브에 주입하고 있는 것입니다.
  5. 마지막으로 외부 지시문을 직접 호출합니다.

⚠️ 보정: 원문은 다음과 같이 주장했다. restrict:'E' "내부 지시문의 데이터가 외부 지시문에서 사용 가능하도록 보장하기 위해" 필요하다고 하지만, 실제로는 그런 역할을 하지 않고 단지 제어만 할 뿐입니다. 방법 지시문을 작성할 수 있습니다. 중첩이 가능한 이유는 컴파일러가 방금 삽입한 템플릿 내부로 계속 진입하기 때문입니다. 데이터를 공유하려면 다음을 사용하세요. require controller.

코드가 성공적으로 실행되면 다음과 같은 출력이 나타납니다.

출력:

중첩된 지시어

출력에서,

  • 외부 및 내부 디렉티브가 모두 호출되었으며, 두 div 태그 안의 텍스트가 모두 표시되는 것을 확인할 수 있습니다.

마크업을 렌더링하는 것은 디렉티브의 절반에 불과하며, 나머지 절반은 사용자의 반응에 대응하는 것입니다.

지침에서 이벤트 처리

이벤트 마우스 클릭이나 버튼 클릭과 같은 동작은 디렉티브 자체 내에서 처리할 수 있습니다. 이는 `link` 함수를 사용하여 구현됩니다. `link` 함수는 디렉티브가 HTML 페이지의 DOM 요소에 연결될 수 있도록 해줍니다.

구문 :

링크 함수의 구문은 아래와 같습니다.

link: function ($scope, element, attrs)

링크 함수는 일반적으로 범위, 디렉티브가 연결된 요소, 대상 요소의 속성이라는 세 가지 매개변수를 받습니다. 필요한 경우 컨트롤러와 트랜스클루드 함수라는 두 가지 매개변수가 추가로 전달됩니다.

컴파일 단계와 링크 단계의 차이점

AngularJS는 디렉티브를 두 단계에 걸쳐 처리하며, 어느 단계가 어느 단계인지 알면 코드가 어디에 위치해야 하는지 알 수 있습니다.

  • 편집하다 템플릿 요소에서 스코프가 존재하기 전에 한 번 실행됩니다. 모든 클론이 공유하는 구조적 편집에 적합합니다.
  • (링크) 템플릿이 복제되고 스코프가 연결된 후 인스턴스당 한 번 실행됩니다. DOM 리스너 및 스코프 읽기 관련 코드는 여기에 속합니다.

컴파일에는 스코프가 없으므로 데이터가 필요한 모든 것은 링크에 속해야 합니다. 이것이 바로 아래 예제에서 정의하는 이유입니다. link 혼자.

이를 달성하는 방법을 예를 통해 살펴보겠습니다. 스크린샷에는 아래 네 가지 항목에 번호가 매겨져 있습니다.

지시문에서 이벤트 처리

<!DOCTYPE html>
<html>
<head>
    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>
<body>

<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp">
    <div ng-guru="">Click Me</div>
</div>

<script type="text/javascript">

    var app = angular.module('DemoApp',[]);

    app.directive('ngGuru',function(){
        return {

            link:function($scope,element,attrs) {
                element.bind('click',function () {
                    element.html('You clicked me');
                });}
        }});
</script>

</body>
</html>

Code 설명

  1. AngularJS에서 정의된 `link` 함수를 사용하여 디렉티브가 HTML DOM의 이벤트에 접근할 수 있도록 합니다.
  2. 우리는 HTML DOM 요소(이 예에서는 "div" 요소)의 이벤트에 응답하기 위해 'element' 키워드를 사용합니다. 그런 다음 'bind' 함수를 사용하여 해당 요소의 클릭 이벤트에 사용자 지정 기능을 추가합니다. 'click'은 모든 HTML 컨트롤의 클릭 이벤트를 나타내는 데 사용되는 키워드입니다.
  3. 여기서 우리는 요소(이 경우 div 요소)의 내부 HTML을 'You clicked me'라는 텍스트로 바꾸고 싶다고 말하고 있습니다.
  4. 여기서는 ng-guru 사용자 정의 지시문을 사용하도록 div 태그를 정의합니다.

💡 Tip 지시문은 사용 후 정리를 해야 합니다. 내부 요소보다 오래 남아있는 리스너를 모두 제거해야 합니다. element.on('$destroy', ...)또는 페이지에서 메모리 누수가 발생합니다.

코드가 성공적으로 실행되면 다음과 같은 출력이 나타납니다.

출력:

지시문에서 이벤트 처리

  • 처음에 사용자에게는 'Click Me'라는 텍스트가 표시됩니다. 이는 div 태그 안에 해당 텍스트가 정의되어 있기 때문입니다. div 태그를 클릭하면 아래와 같은 내용이 표시됩니다.

지시문에서 이벤트 처리

위의 예시들은 모두 동일한 정의 객체의 속성 중 하나 또는 두 개만 사용했습니다. 전체 속성 세트를 숙지해 두는 것이 좋습니다.ping 손에 쥐어주세요.

지시어 정의 객체 속성 참조

디렉티브 팩토리가 반환하는 객체는 다음과 같습니다. 지시문 정의 객체각 속성은 지시문의 동작 방식에 대한 하나의 질문에 답합니다.

부동산 태만 그것이하는 일
얽매다 'EA' 어떤 형식이 일치하나요? E 요소, A 속성, C 클래스, M 주석
이 템플릿 없음 일치하는 요소에 인라인 마크업이 삽입되었습니다.
템플릿URL 없음 템플릿 파일 경로는 한 번 가져온 후 캐시됩니다.
범위 그릇된 false는 부모 스코프를 공유하고, true는 자식 객체를 생성하여 격리합니다.
제어 장치 없음 API를 노출하는 생성자는 다른 지시문에서 요구할 수 있습니다.
컨트롤러 없음 템플릿 내부 컨트롤러의 별칭
필요 없음 주입할 다른 디렉티브의 컨트롤러입니다. ^는 부모를 검색하고, ^^는 자신을 건너뛰며, ?는 선택 사항입니다.
링크 없음 인스턴스별 함수: 범위, 요소, 속성, 컨트롤러, 포함 함수
편집하다 없음 스코프가 존재하기 전에 템플릿에서 한 번 실행됩니다.
트랜스클루드 그릇된 ng-transclude의 원래 내부 마크업을 유지합니다.
우선 0 공유 요소에 대한 컴파일 순서: 높은 순서부터 먼저 실행됩니다.
단말기 그릇된 해당 요소에 대한 우선순위가 낮은 지시를 중지합니다.
교체 그릇된 요소를 템플릿으로 교체합니다. 1.3 버전부터 더 이상 사용되지 않습니다.

💡 Tip 로 시작 restrict, template link, 추가 scope 재사용을 위해, controller require 지시 대 지시 통화의 경우, 그리고 떠나십시오. priority terminal 혼자.

자주 묻는 질문

AngularJS 1.5에서 추가된 컴포넌트는 요소만 매칭하고, 격리된 스코프를 제공하며, 컨트롤러 역할을 하는 등 명확한 기본 설정을 가진 디렉티브입니다. 독립적인 뷰를 구현할 때는 컴포넌트를 사용하고, 링크 레벨 DOM 접근이 필요할 때는 디렉티브를 사용하세요.

일반적으로 이름이 올바르게 정규화되지 않았거나, 제한 사항이 사용한 형식을 제외합니다. 내 이름으로 등록된 지시문입니다.Box mybox가 아닌 my-box와 일치하며, 요소 태그는 E를 포함하도록 제한해야 합니다.

예. AI 어시스턴트는 격리 범위를 입력 및 출력 데코레이터에 매핑하고 템플릿을 구성 요소 템플릿에 매핑합니다. Rev트랜스클루전과 링크 함수 DOM 코드는 변환이 깔끔하지 않은 경우가 많으므로 직접 살펴보세요.

AI 비서가 생성합니다 단위 테스트 지시문을 컴파일하고, 스코프를 연결하고, 렌더링된 출력에 대해 검증하는 스켈레톤입니다. 예외적인 경우를 나열하는 데 유용하므로 생성된 검증 결과를 시작 초안으로 활용하세요.

마크업이 한두 줄을 넘어서면 `templateUrl`을 사용하세요. 이 파일은 일반 HTML 도구로 편집할 수 있으며, 한 번만 가져온 후 이후에는 템플릿 캐시에서 제공됩니다.

이 게시물을 요약하면 다음과 같습니다.