1

중첩 된 지시문을 통해 중계를 내리고 가장 안쪽의 지시문에 데이터를 바인딩하는 방법을 파악하려고합니다. 데이터를 데이터 목록에 바인딩하는 목록 유형 컨트롤과 같이 생각하면 데이터를 표시하는 데 사용할 템플릿이 삽입됩니다. 다음은 단일 값에 바인딩 된 기본 예제입니다 (여기에는 plunk). 당신이 볼 수 있듯이중첩 된 지시문을 통해 각도에서 Transclusion을 전달하는 방법은 무엇입니까?

HTML

<body ng-app="myApp" ng-controller="AppCtrl as app"> 
    <outer model="app.data"><div>{{ source.name }}</div></outer> 
</body> 

자바 스크립트

angular.module('myApp', []) 

.controller('AppCtrl', [function() { 
    var ctrl = this; 

    ctrl.data = { name: "Han Solo" }; 

    ctrl.welcomeMessage = 'Welcome to Angular'; 
}]) 

.directive('outer', function(){ 
    return { 
     restrict: 'E', 
     transclude: true, 
     scope: { 
      model: '=' 
     }, 
     template: '<div class="outer"><inner my-data="model"><div ng-transclude></div></div></div>' 
    }; 
}) 

.directive('inner', function(){ 
    return { 
     restrict: 'E', 
     transclude: true, 
     scope: { 
      source: '=myData' 
     }, 
     template :'<div class="inner" my-transclude></div>' 
    }; 
}) 

.directive('myTransclude', function() { 
    return { 
     restrict: 'A', 
     transclude: 'element', 
     link: function(scope, element, attrs, controller, transclude) { 
      transclude(scope, function(clone) { 
       element.after(clone); 
      }) 
     } 
    } 
}); 

의 매개자 비트가 나타나지 않습니다. 이견있는 사람?

+0

사용자 정의 transclude 지시문이 있어야합니까? –

+0

transclude 시도 : { "inner": "inner"} 사실이 아니십니까? – nixkuroi

+0

최종 출력물을 원하는대로 이해하는 데 도움이 될까요? '

여기에 반입 내용은
'입니까? – Zach

답변

2

. 귀하의 코드에서 발견 된 문제는 기본적으로 transclude가 부모 범위로 컴파일되고 있다는 것입니다. 그렇다면 지시문의 컴파일 단계를 구현하여 문제를 해결할 수 있습니다 (링크 단계 전에 발생 함). 따라서, 귀하의 dirictive 아래의 코드를 다음과 같이 표시됩니다

app.directive('inner', function() { 
    return { 
     restrict: 'E', 
     transclude: true, 
     scope: { 
      source: '=myData' 
     }, 
     template: '<div class="inner" ng-transclude></div>', 
     compile: function (tElem, tAttrs, transclude) { 
      return function (scope, elem, attrs) { // link 

       transclude(scope, function (clone) { 
        elem.children('.inner').append(clone); 
       }); 
      }; 
     } 
    }; 
}); 

당신이 범위를 격리 있어요 위해 transclude 당신의 지시를 강요하는이 방법을.

+0

그건 흥미로운 트릭입니다! 내가 읽은 모든 것은 더 이상 컴파일 함수를 사용할 필요가 없다고 말하지만, 여전히 유용한 경우가있는 것으로 보입니다. 나는 원래의 질문을 해결할 때 대답으로 표시했다. – Jason

1

당신은 모든 방법 세 번째 지침 아래로 당신의 transclude을 통과 할 수 있지만, 내가 볼 문제가 범위 오버라이드이다. 당신은 {{ source.name }}inner 지침에서 가고 싶어하지만, 시간은 첫 번째 지침이 컴파일 :

template: '<div class="outer"><inner my-data="model"><div ng-transclude></div></div></div>'

{{ source.name }} 이미 outer의 범위를 사용하여 컴파일되었습니다. 내가 원하는 방식대로 작동하는 것을 볼 수있는 유일한 방법은 수동으로 $compile으로 처리하는 것입니다. 그러나 나보다 똑똑한 사람은 다른 방법을 생각할 수도 있습니다.

Demo Plunker

+0

감사 Zach 정보를 얻으려면 저를 올바른 방향으로 가야합니다. 내 문제를 해결하는 방법에 대한 내 대답을 참조하십시오. – Jason

2

감사 자크의 대답에, 나는 내 문제를 해결하기 위해 다른 방법을 찾아 냈다. 이제 템플릿을 별도의 파일에 저장하고 URL을 범위를 통과시킨 다음 ng-include와 함께 삽입합니다. 해결책은 Plunk입니다.

HTML :

<body ng-app="myApp" ng-controller="AppCtrl as app"> 
    <outer model="app.data" row-template-url="template.html"></outer> 
</body> 

템플릿 :

<div>{{ source.name }}</div> 

자바 스크립트 : 사용자 정의 transclude 지시 또는 까다로운을 사용할 필요가 없습니다이 경우

angular.module('myApp', []) 

.controller('AppCtrl', [function() { 
    var ctrl = this; 

    ctrl.data = { name: "Han Solo" }; 
}]) 

.directive('outer', function(){ 
    return { 
     restrict: 'E', 
     scope: { 
      model: '=', 
      rowTemplateUrl: '@' 
     }, 
     template: '<div class="outer"><inner my-data="model" row-template-url="{{ rowTemplateUrl }}"></inner></div>' 
    }; 
}) 

.directive('inner', function(){ 
    return { 
     restrict: 'E', 
     scope: { 
      source: '=myData', 
      rowTemplateUrl: '@' 
     }, 
     template :'<div class="inner" ng-include="rowTemplateUrl"></div>' 
    }; 
}); 
+0

DOM을 조작하고 적절한 범위로 수동으로 컴파일하는 것보다 훨씬 쉽고 간단합니다. – Zach