2016-08-11 2 views
0

여기에 문제가 있습니다. 나는 주 지시어이라고하는 제 3 자 지시문을 가지고있다.AngularJS가 지시기 제어기 기능을 오버라이드합니다.

app.directive('mainDirective', function() { 
    return { 
    scope: { 
     foo: '&' 
     // attrs 
    }, 
    controller: function($scope) { 

     $scope.click = function() { 
     window.alert($scope.foo()); 
     } 

    }, 
    template: '<button ng-click="click()">Click me</button>' 
    } 
}); 

그래서 난 내 자신의 지시라는 만들고 싶어 부모 - 지시 타사 지시 속성에 대한 응용 프로그램 고유의 디폴트 값을 할당하는.

app.directive('parentDirective', function() { 
    return { 
    scope: { 
     foo: '&?', 
     attr2: '=' 
     // lots of attrs 
    }, 
    controller: function($scope) { 


     $scope.attr1 = "some default value" 

     $scope.foo = function() { 
     return "not overrided" 
     } 

     if (this.foo) { 
     $scope.foo = this.foo 
     } 

    }, 
    template: '<div class="some-styling"><main-directive foo="foo()" attr1="attr1" attr2="attr2"></main-directive></div>' 
    } 
}); 

내가 부모 - 지시 논리를 유지 다른 아이 지침 만들고 싶어. 특성을 쉽게 오버로드 할 수 있습니다. "컴파일"기능을 사용할 수 있습니다. 하지만 기능 우선 적용은 가능한가?

app.directive('childDirective', function() { 

    return { 
    scope: false, 
    require: 'parentDirective', 
    link: function(scope, element, attr, controller) { 

     controller.foo = function() { 
     return "overrided"; 
     } 

    }, 
    compile: function(element, attr) { 
     attr.attr2 = "attr2"; 
    } 
    } 
}); 

격리 된 대신 하위 범위를 사용하면 모든 일을 쉽게 수행 할 수 있습니다. 또는 템플릿을 사용하여 확장을 사용합니다. 그러나 템플릿을 사용하여 지시문을 확장하는 경우 상위 "범위"및 "템플릿"정의를 하위 지시문에 복사하고 우아한 기본이 아닌 속성을 모두 전달해야합니다. 이는 우아한 해결책처럼 보이지 않습니다.

그래서 중요한 질문은 전달 특성없이 격리 된 범위를 사용하여 부모 지정 함수를 재정의 할 수있는 방법입니다. 여기

DEMO

+0

$ parent를 사용해 보셨나요? 함수가 부모 범위에 있으면 $ parent를 사용하여 함수에 액세스 할 수 있습니다. – acostela

+0

그래, 부모와 자식 지시어 사이에 ng-if 지시어가 있으면 어떨까요? $ parent IMHO를 사용하는 것은 해결책이 아닙니다. $ 부모가 나쁜 연습으로 간주된다는 사실에도 불구하고. – dagi12

답변

0

좋아, 나는 몇 가지 연구를하고 거기 여러 가지 방법이있을 수 있음을 밝혀

범위 상속 아이 지시어는 자신을 생성하지 않기 때문에

범위 - 부모 지시어 부모 범위에서 새로운 메소드를 생성합니다. 따라서 컴파일하는 동안 속성을 수정하고 재정의 된 foo 메소드를 지정할 수 있습니다. 여기

app.directive('parentDirective', function() { 
    return { 
    scope: { 
     fooImpl: '&?', 
     // lots of attrs 
    }, 
    controller: function($scope) { 

     $scope.foo = function() { 
     if ($scope.fooImpl) { 
      return $scope.fooImpl(); 
     } 
     return "not overrided"; 
     } 

    }, 
    template: '<div class="some-styling"><main-directive foo="foo()"></main-directive></div>' 
    } 
}); 

app.directive('childDirective', function() { 

    return { 
    scope: false, 
    require: 'parentDirective', 
    controller: function($scope) { 

     $scope.foo = function() { 
     return "overrided"; 
     } 

    }, 
    compile: function(element, attr) { 
     attr.fooImpl = "foo()"; 
    } 
    } 
}); 

특별한 기능을 제공하는 DEMO1

격리 된 범위

각도에 추가됩니다. 그것은 요소로부터 격리 된 범위를 얻을 수 있습니다. 따라서 링크 단계에서 메소드를 재정의 할 수 있습니다. 여기

app.directive('parentDirective', function() { 
    return { 
    scope: { 
     fooImpl: '&?', 
     // lots of attrs 
    }, 
    controller: function($scope) { 

     $scope.foo = function() { 
     if ($scope.fooImpl) { 
      return $scope.fooImpl(); 
     } 
     return "not overrided"; 
     } 

    }, 
    template: '<div class="some-styling"><main-directive foo="foo()"></main-directive></div>' 
    } 
}); 

app.directive('childDirective', function() { 

    return { 
    scope: false, 
    require: 'parentDirective', 
    link: function(scope, element, attr) { 
     var innerScope = angular.element(element[0]).isolateScope(); 
     innerScope.foo = function() { 
     return "overrided"; 
     } 
    } 
    } 
}); 

DEMO2

컨트롤러 메소드

우리 controllerAs 구문을 사용할 경우이다. 이는 컨트롤러 객체 변수를 범위로 노출한다는 것을 의미합니다. 연결 단계에서 하위 지시문의 함수를 재정의 할 수 있습니다.여기

app.directive('parentDirective', function() { 
    return { 
    scope: { 
     fooImpl: '&?', 
     // lots of attrs 
    }, 
    controller: function($scope) { 

     var vm = this; 

     vm.foo = function() { 
     return "not overrided"; 
     } 

    }, 
    controllerAs : 'vm', 
    template: '<div class="some-styling"><main-directive foo="vm.foo()"></main-directive></div>' 
    } 
}); 

app.directive('childDirective', function() { 

    return { 
    scope: false, 
    require: 'parentDirective', 
    link: function (scope, element, attr, controller) { 

     controller.foo = function() { 
     return "overrided"; 
     } 


    } 
    } 
}); 

DEMO3

트랜스 클루 전

입니다 실질적으로는 별도의 부모와 자식 지침 및 트랜스 클루 전을 사용과 같은 일을 할 수 있습니다. 그러나 어쨌든 그것은 위의 접근 방식의 조합 일 것입니다. 감사합니다. "Extending an existing directive in AngularJS"

관련 문제