격리 된 범위를 사용하지 않고 지시문 내에서 부모 범위의 함수를 호출하는 방법을 찾을 수없는 것 같습니다. 격리 된 범위를 사용하는 경우 격리 된 영역에서 “&”를 사용하여 부모 범위의 함수에 액세스 할 수 있지만 필요하지 않은 경우 격리 된 범위를 사용하면 결과가 발생한다는 것을 알고 있습니다. 다음 HTML을 고려하십시오.
<button ng-hide="hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
이 간단한 예제에서는 JavaScript 확인 대화 상자를 표시하고 확인 대화 상자에서 “확인”을 클릭하는 경우에만 doIt ()을 호출하려고합니다. 격리 된 범위를 사용하면 간단합니다. 지시문은 다음과 같습니다.
.directive('confirm', function () {
return {
restrict: 'A',
scope: {
confirm: '@',
confirmAction: '&'
},
link: function (scope, element, attrs) {
element.bind('click', function (e) {
if (confirm(scope.confirm)) {
scope.confirmAction();
}
});
}
};
})
그러나 문제는 격리 된 범위를 사용하고 있기 때문에 위의 예제에서 ng-hide는 더 이상 부모 범위에 대해 실행되지 않고 격리 된 범위에서 실행 됩니다 (모든 지시문에서 격리 된 범위를 사용하면 해당 요소의 모든 지시문이 격리 된 범위 사용). 다음은 ng-hide가 작동하지 않는 위 예제 의 jsFiddle 입니다. (이 바이올린에서는 입력 상자에 “예”를 입력 할 때 버튼이 숨겨져 야합니다.)
대안은 격리 된 범위를 사용하지 않는 것입니다.이 지시문의 범위를 격리 할 필요가 없기 때문에 실제로 여기에서 원하는 것입니다. 내가 가진 유일한 문제는 격리 된 범위에서 전달하지 않으면 부모 범위에서 메서드를 어떻게 호출 합니까?
여기에 격리 된 범위를 사용하지 않고 ng-hide가 잘 작동 하는 jsfiddle 이 있지만 물론 confirmAction () 호출이 작동하지 않으며 작동하는 방법을 모릅니다.
내가 정말로 찾고있는 대답은 격리 된 범위를 사용하지 않고 외부 범위에서 함수를 호출하는 방법입니다. 이 확인 대화를 다른 방식으로 작동시키는 데 관심이 없습니다.이 질문의 요점은 외부 범위를 호출하는 방법을 알아 내고 부모 범위에 대해 다른 지시문이 작동하도록하는 것입니다.
또는 다른 지시문이 부모 범위에 대해 여전히 작동하는 경우 격리 된 범위를 사용하는 솔루션에 대해 듣고 싶지만 이것이 가능하다고 생각하지 않습니다.
답변
답변
AngularJS에서 $ parse 서비스를 사용하고 싶습니다.
따라서 귀하의 예를 들어 :
.directive('confirm', function ($parse) {
return {
restrict: 'A',
// Child scope, not isolated
scope : true,
link: function (scope, element, attrs) {
element.bind('click', function (e) {
if (confirm(attrs.confirm)) {
scope.$apply(function(){
// $parse returns a getter function to be
// executed against an object
var fn = $parse(attrs.confirmAction);
// In our case, we want to execute the statement in
// confirmAction i.e. 'doIt()' against the scope
// which this directive is bound to, because the
// scope is a child scope, not an isolated scope.
// The prototypical inheritance of scopes will mean
// that it will eventually find a 'doIt' function
// bound against a parent's scope.
fn(scope, {$event : e});
});
}
});
}
};
});
$ parse를 사용하여 속성을 설정하는 것과 관련이 있지만 여기에 오면 그 다리를 건너도록하겠습니다.
답변
hideButton
부모 범위를 명시 적으로 호출 합니다.
여기 바이올린이 있습니다 : http://jsfiddle.net/pXej2/5/
업데이트 된 HTML은 다음과 같습니다.
<div ng-app="myModule" ng-controller="myController">
<input ng-model="showIt"></input>
<button ng-hide="$parent.hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
</div>
답변
내가 가진 유일한 문제는 격리 된 범위에 전달하지 않으면 부모 범위에서 메서드를 어떻게 호출합니까?
여기에 격리 된 범위를 사용하지 않고 ng-hide가 잘 작동하는 jsfiddle이 있지만 물론 confirmAction ()에 대한 호출이 작동하지 않으며 작동하는 방법을 모릅니다.
먼저 작은 요점 :이 경우 외부 컨트롤러의 범위는 지시문 범위의 상위 범위가 아닙니다. 외부 컨트롤러의 범위 는 지시문의 범위입니다. 즉, 지시문에 사용 된 변수 이름은 컨트롤러의 범위에서 직접 조회됩니다.
다음으로, 이 버튼 attrs.confirmAction()
은 쓰기 가 작동하지 않습니다 attrs.confirmAction
.
<button ... confirm-action="doIt()">Do It</button>
은 "doIt()"
문자열이며, 예를 들어 문자열을 호출 할 수 없습니다 "doIt()"()
.
귀하의 질문은 실제로 다음과 같습니다.
이름이 문자열 인 경우 함수를 어떻게 호출합니까?
JavaScript에서는 주로 다음과 같이 점 표기법을 사용하여 함수를 호출합니다.
some_obj.greet()
그러나 배열 표기법을 사용할 수도 있습니다.
some_obj['greet']
인덱스 값이 어떻게 문자열 인지 주목하십시오 . 따라서 지시문에서 간단히 다음과 같이 할 수 있습니다.
link: function (scope, element, attrs) {
element.bind('click', function (e) {
if (confirm(attrs.confirm)) {
var func_str = attrs.confirmAction;
var func_name = func_str.substring(0, func_str.indexOf('(')); // Or func_str.match(/[^(]+/)[0];
func_name = func_name.trim();
console.log(func_name); // => doIt
scope[func_name]();
}
});
}