Angular JS : 범위가있는 지시문 컨트롤러가 이미있을 때 지시문 링크 기능이 필요한 것은 무엇입니까?


199

범위 및 템플릿에서 일부 작업을 수행해야합니다. link함수 또는 함수 에서 모두 할 수있는 것 같습니다 controller(둘 다 범위에 액세스 할 수 있기 때문에).

link컨트롤러가 아닌 기능 을 사용해야하는 경우는 언제 입니까?

angular.module('myApp').directive('abc', function($timeout) {
    return {
        restrict: 'EA',
        replace: true,
        transclude: true,
        scope: true,
        link: function(scope, elem, attr) { /* link function */ },
        controller: function($scope, $element) { /* controller function */ }
    };
}

또한 나는 그것이 link비 각형 세계 라는 것을 이해합니다 . 그래서, 내가 사용할 수 있습니다 $watch, $digest하고 $apply.

link컨트롤러가 이미있을 때 기능 의 의미는 무엇입니까 ?


9
" 또한 링크는 비 각형 세계라는 것을 이해합니다. 따라서 $watch, $digest및을 사용할 수 있습니다 $apply. "
musically_ut

2
내부에는 link각도 마법이 없습니다. 즉, 양방향 바인딩 등이 없습니다. 우리가 사용할 수있는 각도의 API가 있습니다.
Yugal Jindle

답변:


299

and 함수 와의 초기 투쟁과 그들에 대해 많은 것을 읽은 후에 , 나는 이제 대답이 있다고 생각합니다.linkcontroller

먼저 이해 하자.

각도 지시어는 간단히 말하면 어떻게 작동합니까?

  • 템플릿으로 시작합니다 (문자열로 또는 문자열로로드 됨)

    var templateString = '<div my-directive>{{5 + 10}}</div>';

  • 자, 이것은 각도 요소templateString 로 싸여 있습니다.

    var el = angular.element(templateString);

  • 를 사용 하여 링크 함수를 다시 얻기 위해 el컴파일합니다 .$compile

    var l = $compile(el)

    여기에 무슨 일이 일어나는가?

    • $compile 전체 템플릿을 살펴보고 인식하는 모든 지시문을 수집합니다.
    • 발견 모든 지시문은 재귀 적 으로 컴파일 되고 해당 link기능이 수집됩니다.
    • 그런 다음 모든 link함수가 새 link함수에 래핑 되고로 반환됩니다 l.
  • 마지막으로, scopel(링크) 함수에 기능을 제공 하여 랩핑 된 링크 함수를 이것 scope과 해당 요소로 추가로 실행합니다 .

    l(scope)

  • 이것은 template에 새로운 노드를 추가 DOM하고 호출 하여 DOM에서 템플릿과 공유 controller되는 범위에 시계를 추가합니다 .

여기에 이미지 설명을 입력하십시오

컴파일링크컨트롤러 비교 :

  • 모든 지시문은 한 번만 컴파일 되며 재사용을 위해 링크 기능이 유지됩니다. 따라서 지시문의 모든 인스턴스에 적용 가능한 것이 있으면 지시문의 compile기능 내에서 수행해야합니다 .

  • 이제 컴파일 후 템플릿DOM에link 첨부하는 동안 실행되는 함수 가 있습니다 . 따라서 지시어의 모든 인스턴스와 관련된 모든 것을 수행합니다. 예를 들어 : 이벤트 첨부 , 범위에 따라 템플리트 변경

  • 마지막으로, 컨트롤러 는 지시가 작동하는 동안 DOM(연결된 후) 작동하고 반응 할 수 있어야합니다 . 따라서:

    (1) 링크로 뷰 [ V ] (즉, 템플릿)를 설정 한 후 . MVC 에서 우리 $scope의 [ M ] 그리고 $controller우리의 [ C ]

    (2) 시계를 설정 하여 $ scope 와의 양방향 바인딩을 활용하십시오 .

    (3) $scope런타임 중에 템플릿을보고있는 것이기 때문에 컨트롤러에 시계가 추가 될 것으로 예상됩니다.

    (4) 마지막으로, controller관련 지시문들 사이에서 의사 소통을 할 수 있도록 사용됩니다. ( https://docs.angularjs.org/guide/directive의myTabs 예제 와 같이 )

    (5) 우리가이 모든 것을 link기능뿐만 아니라 우려의 분리에 대해서도 할 수 있다는 것은 사실이다 .

따라서 마지막으로 모든 조각에 완벽하게 맞는 다음을 얻습니다.

여기에 이미지 설명을 입력하십시오


5
나는 또한이 기사가 실행 순서를 이해하는 데 도움이된다는 것을 발견했다 : AngularJS 지시어 내의 컴파일 및 링크 함수의 핵심
BobbyA

4
좋은 설명입니다. 링크 기능 전에 컨트롤러가 호출된다는 것을 언급하고 싶습니다.
jsbisht

38
링크 전에 컨트롤러 실행
Royi Namir

10
스택 오버플로에서 편집 내용이 6 자 이상이어야하므로이 답변에서 맞춤법을 수정할 수는 없습니다.
user1886323

79

컨트롤러가 필요한 이유

의 차이 link와는 controller당신이 당신의 DOM에 둥지 지시에 원하는 중첩 된 것과 부모 지시어에서 API 함수를 노출 할 때 활동하기 시작.

로부터 문서 :

모범 사례 : API를 다른 지시문에 노출하려는 경우 컨트롤러를 사용하십시오. 그렇지 않으면 링크를 사용하십시오.

당신이이 개 지침이하고 싶은 말 my-form등을 my-text-input원하는 my-text-input지시어는 내부 표시 my-form와 다른 곳.

이 경우, 지시문 my-text-input을 정의하는 동안 require 인수를 사용하여 DOM 요소 의 컨트롤러가 필요 하다는 것을 알 수 있습니다. 이제 부모 요소의 컨트롤러가 다음 네 번째 인수로 함수에 들어 갑니다 . 해당 컨트롤러에서 함수를 호출하고 부모 지시문과 통신 할 수 있습니다.parentrequire: '^myForm'injectedlink$scope, element, attributes

또한 그러한 컨트롤러를 찾지 못하면 오류가 발생합니다.

링크를 전혀 사용하지 않는 이유

사용에 진짜 필요가 없습니다 link하나가 정의되면 기능 controller(가)부터 $scope온 볼 수는 controller. 모두를 정의하면서 또한, linkcontroller, 하나는 필요 두 (의 호출의 순서에주의해야합니까 controller전에 실행됩니다).

그러나 Angular 방식에 따라 대부분의 DOM 조작 및 양방향 바인딩 사용 $watchers은 일반적으로 link함수 에서 수행되는 반면 자식 및 $scope조작을 위한 API 는에서 수행됩니다 controller. 이것은 어렵고 빠른 규칙은 아니지만 그렇게하면 코드가 더욱 모듈화되고 문제를 분리하는 데 도움이됩니다 (컨트롤러는 directive상태 link를 유지 하고 기능은 DOM+ 외부 바인딩을 유지함 ).


훌륭합니다. 이제 질문의 두 번째 부분을 도와 줄 수 있습니까?
Yugal Jindle

다른 지시어와 통신하는 데 사용할 수있는 컨트롤러가 존재했기 때문입니다. 그래서 무엇이 필요 link했습니까?
Yugal Jindle

1
당신의 대답은 어떻게 든 실제 질문에 대답하지 않습니다.
Yugal Jindle

1
정의 할 때 발생하는 문제가 controller있습니까? 왜 컨트롤러 정의를 피하기 위해 완전히 새로운 기능을 발명하고 싶습니까?
Yugal Jindle

1
@scalaGirl의 링크가 더 이상 작동하지 않는 것 같습니다
Minato

17

controller함수 / 객체 추상화 모델 - 뷰 - 제어기 (MVC)을 나타낸다. MVC에 대한 새로운 글은 없지만 여전히 각도의 가장 중요한 장점입니다. 우려를 더 작은 조각으로 나눕니다. 그리고 당신이에 반응 할 필요가 그렇다면, 아무것도 더, 그것 뿐이다 Model에서 오는 변화 View(가) Controller올바른입니다 사람이 그 일을 할.

link기능 에 대한 이야기 는 다릅니다. MVC와 다른 관점에서 왔습니다. 일단 우리가 controller/model/view (템플릿) 의 경계를 넘어 가고 싶다면 정말 필수적 입니다.

link함수에 전달 된 매개 변수로 시작해 봅시다 .

function link(scope, element, attrs) {
  • scope 는 Angular 범위 객체입니다.
  • element 는이 지시어가 일치하는 jqLite-wrapped 요소입니다.
  • attrs 는 정규화 된 속성 이름과 해당 값을 가진 객체입니다.

link컨텍스트에 넣으려면 모든 지시문이이 초기화 프로세스 단계를 수행하고 있음을 언급해야합니다 : Compile , Link . Brad Green과 Shyam Seshadri 에서 발췌 : Angular JS :

컴파일 단계 (링크의 자매, 명확한 그림을 얻으려면 여기를 언급하십시오) :

이 단계에서 Angular는 DOM을 안내하여 템플릿에 등록 된 모든 지시문을 식별합니다. 그런 다음 각 지시문에 대해 지시문 규칙 (템플릿, 바꾸기, 변환 등)을 기반으로 DOM을 변환하고 컴파일 함수가있는 경우이를 호출합니다. 결과는 컴파일 된 템플릿 함수입니다.

링크 단계 :

뷰를 동적으로 만들기 위해 Angular는 각 지시문에 대해 링크 함수를 실행합니다. 링크 함수는 일반적으로 DOM 또는 모델에서 리스너를 작성합니다. 이 리스너는 항상 뷰와 모델을 동기화 상태로 유지합니다.

사용 방법에 대한 좋은 예는 사용자 지정 지시문 만들기link 에서 찾을 수 있습니다 . "날짜-시간"을 페이지에 삽입하는 DOM을 조작하는 지시문 작성 예제 ( 초마다 새로 고침)를 참조하십시오.

위의 풍부한 소스 에서 가져온 짧은 스 니펫은 DOM을 사용한 실제 조작을 보여줍니다. $ timeout 서비스에 연결된 기능이 있으며, 메모리 누수를 피하기 위해 소멸자 호출 에서 지워집니다.

.directive('myCurrentTime', function($timeout, dateFilter) {

 function link(scope, element, attrs) {

 ...

 // the not MVC job must be done
 function updateTime() {
   element.text(dateFilter(new Date(), format)); // here we are manipulating the DOM
 }

 function scheduleUpdate() {
   // save the timeoutId for canceling
   timeoutId = $timeout(function() {
     updateTime(); // update DOM
     scheduleUpdate(); // schedule the next update
   }, 1000);
 }

 element.on('$destroy', function() {
   $timeout.cancel(timeoutId);
 });

 ...

3
당신은 비교 것 같다 compilerlink. 그들은 왜 link우리가 이미 있었 controller
는지 묻습니다

컨트롤러조차도 더 자세히 설명하기 위해 답변을 확장했습니다. 이제 controllervs 의 개념 link이보다 명확
해져야합니다

1
나는 그 설명을 위해 정착 할 수 있었다. 그러나 그곳은 흐릿한 것 같습니다. 각진 팀의 누군가가 그것을 위해 말할 수 있다면, 어디로 가는지 link또는 어디로 가는지를 볼 수 있다면 좋을 것 controller입니다.
Yugal Jindle

1
그것이 내가 이해하고 싶은 유일한 부분입니다 (충분하지 않은시기는 언제입니까?). 게다가, 나는의 각도의 모든 혜택을받을 controller하고 link상대적으로 추악한입니다. 따라서 각진 팀은 옵션이 아닌 합당한 이유가 있어야합니다.
Yugal Jindle

1
질문 : 컨트롤러가 충분하지 않은 경우 답변 : JQuery 플러그인 사용 또는 문서 ( docs.angularjs.org/api/ng/function/angular.element :)에 언급 된 JQlite 기능 사용과 같은 Angular 경험 이 필요하지 않은 경우 필요합니다. 링크
Hasteq
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.