directive link 함수에 ng-click을 동적으로 추가합니다.
요소를 클릭 가능 또는 클릭 불가능으로 정의할 수 있는 디렉티브를 작성하려고 합니다.이 디렉티브는 다음과 같습니다.
<page is-clickable="true">
transcluded elements...
</page>
결과 HTML은 다음과 같습니다.
<page is-clickable="true" ng-click="onHandleClick()">
transcluded elements...
</page>
이 명령어의 실장은 다음과 같습니다.
app.directive('page', function() {
return {
restrict: 'E',
template: '<div ng-transclude></div>',
transclude: true,
link: function(scope, element, attrs) {
var isClickable = angular.isDefined(attrs.isClickable) && scope.$eval(attrs.isClickable) === true ? true : false;
if (isClickable) {
attrs.$set('ngClick', 'onHandleClick()');
}
scope.onHandleClick = function() {
console.log('onHandleClick');
};
}
};
});
새로운 Atribute를 추가한 후 Angular는 이 Atribute에 대해ng-click
, 따라서, 기동하고 있지 않습니다.추가하려고 했습니다.$compile
Atribute가 설정된 후, 단, 무한 링크/패킷 루프가 발생합니다.
그냥 내부를 확인할 수 있어요onHandleClick()
기능하다isClickable
값은true
근데 어떻게 해야 될지 궁금하네요.다이나믹하게 추가해서ng-click
여러 개의 다른 이벤트와 함께 이 작업을 수행해야 할 수 있기 때문에 이벤트.ng-*
불필요한 오버헤드를 추가하고 싶지 않습니다.좋은 생각 있어요?
뛰어난 솔루션 (신규):
Angular documents를 읽은 후 다음과 같은 사실을 알게 되었습니다.
템플릿을 나타내는 문자열 또는 tElement 및 tAttrs(아래 컴파일 함수 api에서 설명)의 2개의 인수를 사용하여 템플릿을 나타내는 문자열 값을 반환하는 함수로 템플릿을 지정할 수 있습니다.
그래서 저의 새로운 지시는 다음과 같습니다. (이것이 이런 종류의 일에 대해 적절한 "각적" 방법이라고 생각합니다.)
app.directive('page', function() {
return {
restrict: 'E',
replace: true,
template: function(tElement, tAttrs) {
var isClickable = angular.isDefined(tAttrs.isClickable) && eval(tAttrs.isClickable) === true ? true : false;
var clickAttr = isClickable ? 'ng-click="onHandleClick()"' : '';
return '<div ' + clickAttr + ' ng-transclude></div>';
},
transclude: true,
link: function(scope, element, attrs) {
scope.onHandleClick = function() {
console.log('onHandleClick');
};
}
};
});
새로운 템플릿 기능에 주목해 주세요.이제 컴파일하기 전에 해당 함수 내에서 템플릿을 조작합니다.
대체 솔루션(구):
추가된replace: true
명령어를 다시 컴파일할 때 무한 루프 문제를 제거합니다.링크 기능에서는 새로운 속성을 추가한 후 요소를 다시 컴파일합니다.한 가지 주의할 게 있는데ng-transclude
두 번째 컴파일에서는 어떤 것도 제외하려고 하지 않기 위해 요소를 삭제해야 했습니다.왜냐하면 제외할 것이 없기 때문입니다.
현재 제 지시는 다음과 같습니다.
app.directive('page', function() {
return {
restrict: 'E',
replace: true,
template: '<div ng-transclude></div>',
transclude: true,
link: function(scope, element, attrs) {
var isClickable = angular.isDefined(attrs.isClickable) && scope.$eval(attrs.isClickable) === true ? true : false;
if (isClickable) {
attrs.$set('ngClick', 'onHandleClick()');
element.removeAttr('ng-transclude');
$compile(element)(scope);
}
scope.onHandleClick = function() {
console.log('onHandleClick');
};
}
};
});
두 번째 템플릿을 다시 컴파일하는 것은 바람직하지 않다고 생각하기 때문에 첫 번째 템플릿을 컴파일하기 전에 아직 방법이 있다고 생각합니다.
언제든지 ng-click을 다음과 같이 변경할 수 있습니다.
ng-click="isClickable && someFunction()"
커스텀 디렉티브는 필요 없습니다:)
다음은 JSFiddle 데모입니다.http://jsfiddle.net/robianmcd/5D4VR/
갱신된 답변
"The Angular Way"는 수동 DOM 조작이 전혀 아닙니다.그래서 애트리뷰트 추가 및 삭제를 없애야 합니다.
DEMO
템플릿을 다음으로 변경합니다.
template: '<div ng-click="onHandleClick()" ng-transclude></div>'
'에서 'Directive Check'는 'Directive Check'입니다.isClickable
속성을 클릭하여 수행할 작업을 결정합니다.
link: function(scope, element, attrs) {
var isClickable = angular.isDefined(attrs.isClickable) && scope.$eval(attrs.isClickable) === true ? true : false;
scope.onHandleClick = function() {
if (!isClickable) return;
console.log('onHandleClick');
};
}
isClickable Atribute를 디렉티브스코프에 배치하여 동작을 동적으로 변경할 수도 있습니다.
구답(오답)
link
는 템플릿 컴파일 후에 실행됩니다.controller
" " " " " : "
app.directive('page', function() {
return {
restrict: 'E',
template: '<div ng-transclude></div>',
transclude: true,
controller: function(scope, element, attrs) {
// your code
}
};
});
HTML
<div page is-clickable="true">hhhh</div>
JS
app.directive('page', function($compile) {
return {
priority:1001, // compiles first
terminal:true, // prevent lower priority directives to compile after it
template: '<div ng-transclude></div>',
transclude: true,
compile: function(el,attr,transclude) {
el.removeAttr('page'); // necessary to avoid infinite compile loop
var contents = el.contents().remove();
var compiledContents;
return function(scope){
var isClickable = angular.isDefined(attr.isClickable)?scope.$eval(attr.isClickable):false;
if(isClickable){
el.attr('ng-click','onHandleClick()');
var fn = $compile(el);
fn(scope);
scope.onHandleClick = function() {
console.log('onHandleClick');
};
}
if(!compiledContents) {
compiledContents = $compile(contents, transclude);
}
compiledContents(scope, function(clone, scope) {
el.append(clone);
});
};
},
link:function(scope){
}
};
});
브라우저가 'E'로 크래시된 BTW: (
이것은 속성 지원도 추가한 @DiscGolfer 솔루션 버전입니다.
.directive("page", function() {
return {
transclude: true,
replace: true,
template: function(tElement, tAttr) {
var isClickable = angular.isDefined(tAttrs.isClickable) && eval(tAttrs.isClickable) === true ? true : false;
if (isClickable) {
tElement.attr("ng-click", "onHandleClick()");
}
tElement.attr("ng-transclude", "");
if (tAttr.$attr.page === undefined) {
return "<" + tElement[0].outerHTML.replace(/(^<\w+|\w+>$)/g, 'div') + ">";
} else {
tElement.removeAttr(tAttr.$attr.page);
return tElement[0].outerHTML;
}
}
};
보다 범용적이고 완전한 샘플이 제공됩니다.http://plnkr.co/edit/4PcMnpq59ebZr2VrOI07?p=preview
한 문제는 '이러한 문제'라는 것입니다.replace
는 AngularAngular에서 더 사용되지 않습니다.JS.
이렇게 하는 게 좋을 것 같아요.
app.directive('page', function() {
return {
restrict: 'E',
template: '<div ng-transclude></div>',
transclude: true,
link: function(scope, element, attrs) {
var isClickable = angular.isDefined(attrs.isClickable) && scope.$eval(attrs.isClickable) === true ? true : false;
if (isClickable) {
angular.element(element).on('click', scope.onHandleClick);
}
scope.onHandleClick = function() {
console.log('onHandleClick');
};
}
};
});
module.factory("ibDirectiveHelpers", ["ngClickDirective", function (ngClick) {
return {
click: function (scope, element, fn) {
var attr = {ngClick: fn};
ngClick[0].compile(element, attr)(scope, element, attr);
}
};
}]);
용도:
module.controller("demoController",["$scope","$element","ibDirectiveHelpers",function($scope,$element,ibDirectiveHelpers){
$scope.demoMethod=function(){console.log("demoMethod");};
ibDirectiveHelpers.click($scope,$element,"demoMethod()");//uses html notation
//or
ibDirectiveHelpers.click($scope,$element,function(){$scope.demoMethod();});//uses inline notation
}]
언급URL : https://stackoverflow.com/questions/22116470/add-ng-click-dynamically-in-directive-link-function
'source' 카테고리의 다른 글
이미지 동적 추가 리액트 웹 팩 (0) | 2023.03.18 |
---|---|
create-react-app에서 빌드 실행 후 공백 페이지 (0) | 2023.03.18 |
반응 - 다른 구성 요소에 상태를 전달하는 방법 (0) | 2023.03.13 |
WordPress 다중 사이트용 h2o webserver mruby 핸들러는 어떻게 작성합니까? (0) | 2023.03.13 |
워드프레스로 이미지 캡션을 가져오는 기능이 있나요? (0) | 2023.03.13 |