2014-11-03 9 views
0

지시어 요소에 DOM 이벤트를 첨부하여 범위 속성을 업데이트하려고합니다. 불행히도, 나는 이것을 할 수있는 "깨끗한"방법을 찾을 수 없습니다. 이 작업을 지금 수행 할 수있는 유일한 방법은 명시 적으로 처리기 내에서 $apply()을 호출하는 것입니다. 이것은 좋은 습관입니다. 그러나 ng-click="myDOMEventHandler()"과 같은 고유 각도 지시문 (이 코드는 $apply already in progress 예외를 트리거하기 때문에이 코드를 공유하지 못하게됩니다.)Angular 지시어에 DOM 이벤트 추가

DOM 이벤트를 지시문에 추가 할 수 있습니까? 요소를 사용하여 범위 변경을 호출 할 수 있지만 호출 할 필요가 없습니다.

여기에 간단한 의미의 예가 있습니다 You can edit this Plunker as well).

angular.module('myApp', []) 
.directive('myDirective', function ($compile) { 
    return { 
    link: function (scope, element) { 
     scope.keystrokes = 0; 

     var report = angular.element('<div ng-click="increment()">keystrokes: {{keystrokes}}</div>'); 
     element.after(report); 
     $compile(report)(scope); 

     scope.increment = function() { 
     scope.keystrokes += 1; 
     scope.$apply(); 
     }; 

     element.on('keyup', scope.increment); 
    } 
    }; 
}); 

입력에 텍스트를 입력하면 카운터가 증가합니다. 그리고 버튼을 클릭하면 카운터도 증가합니다. 단, $apply already in progress 예외가 발생합니다.

scope.$apply()을 제거하면 예외가 사라지고 범위 속성이 변경되지만 이러한 변경 사항은 표시되지 않습니다.

답변

1

당신은. $ 범위를 사용해야 scope.increment 기능을 내부에 적용하지만 각도 범위 밖이 이벤트를 바인딩대로 element.on('keyup'...)) 내부

$apply을 사용해야하지 않는

angular.module('myApp', []) 
 
.directive('myDirective', function ($compile) { 
 
    return { 
 
    link: function (scope, element) { 
 
     scope.keystrokes = 0; 
 

 
     var report = angular.element('<div>keystrokes and clicks: {{keystrokes}} <button ng-click="increment()">Or click me</button></div>'); 
 
     element.after(report); 
 
     $compile(report)(scope); 
 

 
     scope.increment = function() { 
 
     scope.keystrokes += 1; 
 
     
 
     }; 
 
     
 
     element.on('keyup', function(){ 
 
     
 
     scope.$apply(function(){ 
 
      
 
      scope.increment(); 
 
      
 
     }); 
 
     
 
     
 
     }); 
 
    } 
 
    }; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<body ng-app="myApp"> 
 
    <input my-directive="" /> 
 
</body>

+0

그러나 부모 문서에 마크 업을 넣지 않고이 작업을 수행 할 수있는 방법이 있습니까? ' '에 추가하면 외부 종속성처럼 보입니다. 지시문 자체가이 문제를 처리 할 수 ​​있어야한다고 생각합니다. – Andrew

+0

@Andrew 그 경우에는 범위를 이동할 수 있습니다. $ scope.increment를 element.on ('keyup', ...에 적용하십시오. 각도 범위 밖에서 이벤트가 트리거되고 여기에서 $ apply를 사용하여 범위 수명주기를 수행 할 수 있습니다. – sylwester

+0

감사 당신의 도움을 위해. 이것이 유일한 방법이 될 것 같습니다. 어떤 번거 로움, 나는 또한 범위를 실행해야합니다 $ ('$ 파괴')'깨끗하게 제거하는 이벤트 리스너 및없는 누수가. 이것은 당신이 익명 함수 내에서'scope. $ apply()'를 실행할 수 없다는 것을 의미한다고 생각하지만 중간 함수가 필요하다. 1)'keyup '을 바인드한다. 2) scope $ on ('$ destroy')'to, 3)'scope $ apply()'를 실행합니다. Angal은 이미 자신의 고유 한 지시어로 이미이 모든 작업을 수행하고 있기 때문에 실제로는 Angular가 기본적으로 통합해야합니다. 그러나 이것은 효과가있다! – Andrew