[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 함수 와의 초기 투쟁과 그들에 대해 많은 것을 읽은 후에 , 나는 이제 대답이 있다고 생각합니다.link
controller
먼저 이해 하자.
각도 지시어는 간단히 말하면 어떻게 작동합니까?
-
템플릿으로 시작합니다 (문자열로 또는 문자열로로드 됨)
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
.
-
마지막으로,
scope
이l
(링크) 함수에 기능을 제공 하여 랩핑 된 링크 함수를 이것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 요소 의 컨트롤러가 필요 하다는 것을 알 수 있습니다. 이제 부모 요소의 컨트롤러가 다음 네 번째 인수로 함수에 들어 갑니다 . 해당 컨트롤러에서 함수를 호출하고 부모 지시문과 통신 할 수 있습니다.parent
require: '^myForm'
injected
link
$scope, element, attributes
또한 그러한 컨트롤러를 찾지 못하면 오류가 발생합니다.
링크를 전혀 사용하지 않는 이유
사용에 진짜 필요가 없습니다 link
하나가 정의되면 기능 controller
(가)부터 $scope
온 볼 수는 controller
. 모두를 정의하면서 또한, link
및 controller
, 하나는 필요 두 (의 호출의 순서에주의해야합니까 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);
});
...