Programing

ng-include 노드를 템플릿으로 바꾸시겠습니까?

lottogame 2020. 9. 23. 08:03
반응형

ng-include 노드를 템플릿으로 바꾸시겠습니까?


각도가 처음입니다. 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>

나는 이와 동일한 문제가 있었지만 여전히 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'로 설정하면 원하는 마크 업이 생성됩니다.


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

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

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

HTML에서 :

<blah></blah>

I had the same problem, my 3rd party css stylesheet didn't like the extra DOM-element.

My solution was super-simple. Just move the ng-include 1 up. So instead of

<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>

I simply did:

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

I bet this will work in most situations, even tho it technically isn't what the question is asking.


Another alternative is to write your own simple replace/include directive e.g.

    .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;
                   }
               };
           });

This would then be used as follows:

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

This is the correct way of replacing the children

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

Following directive extends ng-include native directive functionality.

It adds an event listener to replace the original element when content is ready and loaded.

Use it in the original way, just add "replace" attribute:

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

or with attribute notation:

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

Here is the directive (remember to include 'include-replace' module as dependency):

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();
                    };
                });
            }
        }
    };
});

I would go with a safer solution than the one provided by @Brady Isom.

I prefer to rely on the onload option given by ng-include to make sure the template is loaded before trying to remove it.

.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());
            };
        }
    };
}])

No need for a second directive since everything is handled within the first one.

참고URL : https://stackoverflow.com/questions/16496647/replace-ng-include-node-with-template

반응형