ng-include 노드를 템플릿으로 교체 하시겠습니까?


85

각도가 처음입니다. ng-include 노드를 포함 된 템플릿의 내용 으로 바꿀 수 있습니까? 예를 들면 다음과 같습니다.

<div ng-app>
    <script type="text/ng-template" id="test.html">
        <p>Test</p>
    </script>
    <div ng-include src="'test.html'"></div>
</div>

생성 된 html은 다음과 같습니다.

<div ng-app>
    <script type="text/ng-template" id="test.html">
        <p>Test</p>
    </script>
    <div ng-include src="'test.html'">
        <span class="ng-scope"> </span>
        <p>Test</p>
        <span class="ng-scope"> </span>
    </div>
</div>

하지만 내가 원하는 것은 :

<div ng-app>
    <script type="text/ng-template" id="test.html">
        <p>Test</p>
    </script>
    <p>Test</p>
</div>

1
'test.html'URL 대신 템플릿을 사용하려면 작은 따옴표를 제거하십시오.
charlietfl

1
ng-include에 대한 문서의 주석을 읽으면 템플릿은 작은 따옴표로 묶고 url은 넣지 않은 것 같습니다. 또한 관련 stackoverflow 질문
SunnySydeUp

당신은 문서를 읽고 있고 당신이 거꾸로 링크 한 포스트를 게시합니다
charlietfl

답변:


134

나는 이와 동일한 문제가 있었지만 여전히 ng-include의 기능에 동적 템플릿이 포함되기를 원했습니다. 저는 동적 부트 스트랩 툴바를 만들고 있었고 CSS 스타일이 제대로 적용되도록 깔끔한 마크 업이 필요했습니다.

관심있는 사람들을 위해 제가 생각 해낸 해결책은 다음과 같습니다.

HTML :

<div ng-include src="dynamicTemplatePath" include-replace></div>

사용자 지정 지시문 :

app.directive('includeReplace', function () {
    return {
        require: 'ngInclude',
        restrict: 'A', /* optional */
        link: function (scope, el, attrs) {
            el.replaceWith(el.children());
        }
    };
});

위의 예제에서이 솔루션을 사용한 경우 scope.dynamicTemplatePath를 'test.html'로 설정하면 원하는 마크 업이 생성됩니다.


angular v1.2 + 필요
colllin 2014 년


이것은 각도 1.2.5 이상에서 작동합니다. 1.2.4의 경우 ng-include가 다른 ng-include가 있으면 실패합니다. # 5247 때문에 추측 하고 있지만 확실하지 않습니다. 직접 변경 로그 를 참조 하십시오. 다음은 1.2.4에서이 문제를 보여주는 Plunkr입니다 (각도 1.2.5로 변경하고 작동하는지 확인하십시오! :-)
Peter V. Mørch

9
이러한 DOM 조작은 꽤 엉뚱한 데, 포함 된 템플릿의 루트 요소가 ng-repeat와 같은 것을 사용하면 문제가 있습니다. DOM에 결과를 삽입 할 수 없습니다.
Guria

1
이에 대한 내 대답을 참조하십시오. prelink 기능이 이미 자식 요소에서 실행되었으므로 실패합니다.
Sai Dubbaka 2015

28

그래서 @ user1737909 덕분에 ng-include가 갈 길이 아님을 깨달았습니다. 지시문은 더 나은 접근 방식이며 더 명시 적입니다.

var App = angular.module('app', []);

App.directive('blah', function() {
    return {
        replace: true,
        restrict: 'E',  
        templateUrl: "test.html"
    };
});

HTML에서 :

<blah></blah>

2
감사! 겨-포함 솔루션을 찾고 있지만, 이것은 나에게 지침이 더 깨닫게 도움이되었다
매트 김

있다는 사실을 숙지 replace:true템플릿에 중단 표시된 . 지원 중단 상태로 인해이 솔루션을 사용하지 않을 것입니다.
Peter V. Mørch

@ PeterV.Mørch 감사합니다. 관심있는 사람들을 위해 이것은 커밋입니다 : github.com/angular/angular.js/commit/… . 복잡성 (그리고 아마도 다른 이유) 때문에 더 이상 사용되지 않는 것 같습니다.
SunnySydeUp 2014 년

15

나는 똑같은 문제가 있었고, 제 3 자 CSS 스타일 시트는 여분의 DOM 요소를 좋아하지 않았습니다.

내 솔루션은 매우 간단했습니다. ng-include 1을 위로 이동하십시오. 그래서 대신

<md-sidenav flex class="md-whiteframe-z3" md-component-id="left" md-is-locked-open="$media('gt-md')">
  <div ng-include="myService.template"></span>
</md-sidenav>

나는 단순히했다 :

<md-sidenav flex class="md-whiteframe-z3" md-component-id="left" md-is-locked-open="$media('gt-md')" ng-include="myService.template">
</md-sidenav>

나는 이것이 대부분의 상황에서 작동 할 것이라고 장담한다. 심지어 그것이 기술적으로 질문이 요구하는 것이 아니더라도.


10

또 다른 대안은 간단한 교체 / 포함 지시문을 작성하는 것입니다.

    .directive('myReplace', function () {
               return {
                   replace: true,
                   restrict: 'A',
                   templateUrl: function (iElement, iAttrs) {
                       if (!iAttrs.myReplace) throw new Error("my-replace: template url must be provided");
                       return iAttrs.myReplace;
                   }
               };
           });

그러면 다음과 같이 사용됩니다.

<div my-replace="test.html"></div>

9

이것은 아이들을 교체하는 올바른 방법입니다.

angular.module('common').directive('includeReplace', function () {
    return {
        require: 'ngInclude',
        restrict: 'A',
        compile: function (tElement, tAttrs) {
            tElement.replaceWith(tElement.children());
            return {
                post : angular.noop
            };
        }
    };
});

4
내 포함 된 부분 html에는 ng-repeat가 있으며 이것이 해결하는 유일한 대답입니다! 감사합니다.
Saad Benbouzid

나는에서 함수 컨텐츠를 이동했다 compilelink내 요소는 컴파일 단계에서 비어 있기 때문에.
itachi

3

다음 지시문은 ng-include 기본 지시문 기능을 확장합니다.

콘텐츠가 준비되고로드되면 원래 요소를 대체하는 이벤트 리스너를 추가합니다.

원래 방식으로 사용하고 "replace"속성 만 추가하면됩니다.

<ng-include src="'src.html'" replace></ng-include>

또는 속성 표기법 :

<div ng-include="'src.html'" replace></div>

다음은 지시문입니다 ( 'include-replace'모듈을 종속성으로 포함하는 것을 잊지 마십시오) :

angular.module('include-replace', []).directive('ngInclude', function () {
    return {
        priority: 1000,
        link: function($scope, $element, $attrs){

            if($attrs.replace !== undefined){
                var src = $scope.$eval($attrs.ngInclude || $attrs.src);

                var unbind = $scope.$on('$includeContentLoaded', function($event, loaded_src){
                    if(src === loaded_src){
                        $element.next().replaceWith($element.next().children());
                        unbind();
                    };
                });
            }
        }
    };
});

2

@Brady Isom에서 제공하는 것보다 더 안전한 솔루션으로 갈 것입니다.

나는 템플릿을 제거하기 전에로드되었는지 확인하기 위해 에서 제공하는 onload옵션 에 의존하는 것을 선호 ng-include합니다.

.directive('foo', [function () {
    return {
        restrict: 'E', //Or whatever you need
        scope: true,
        template: '<ng-include src="someTemplate.html" onload="replace()"></ng-include>',
        link: function (scope, elem) {
            scope.replace = function () {
                elem.replaceWith(elem.children());
            };
        }
    };
}])

모든 것이 첫 번째 지시문 내에서 처리되므로 두 번째 지시문이 필요하지 않습니다.


각도 1.5를 사용하면 지시문 요소의 첫 번째 자식이 주석이라는 점에 유의하십시오. 나는 다음 NG-포함 요소를 얻을 확인했다 그래서 그 아이로 교체 : let ngInclude = angular.element( element[ 0 ].querySelector( 'ng-include' ) ); ngInclude.replaceWith( ngInclude.children() );
Mattijs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.