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

범위 및 템플릿에서 일부 작업을 수행해야합니다. 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컨트롤러가 이미있을 때 기능 의 의미는 무엇입니까 ?



답변

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기능뿐만 아니라 우려의 분리에 대해서도 할 수 있다는 것은 사실이다 .

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

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


답변

컨트롤러가 필요한 이유

의 차이 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+ 외부 바인딩을 유지함 ).


답변

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);
 });

 ...


답변