Avoid using extra DOM nodes when using nginclude

后端 未结 5 711
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-31 10:23

I\'m struggling to wrap my mind around how to have an ng-include not use an extra DOM element as I\'m building an angular app from a plain-HTML demo. I\'m working with pretty sl

5条回答
  •  失恋的感觉
    2021-01-31 10:41

    With the right setup, you can define your own ngInclude directive that can run instead of the one provided by Angular.js and prevent the built-in directive to execute ever.

    To prevent the Angular-built-in directive from executing is crucial to set the priority of your directive higher than that of the built-in directive (400 for ngInclude and set the terminal property to true.

    After that, you need to provide a post-link function that fetches the template and replaces the element's DOM node with the compiled template HTML.

    A word of warning: this is rather draconian, you redefine the behavior of ngInclude for your whole application. I therefore set the directive below not on myApp but inside one of my own directives to limit its scope. If you want to use it application-wide, you might want to make its behavior configurable, e.g. only replace the element if a replace attribute is set in the HTML and per default fall back to setting innerHtml.

    Also: this might not play well with animations. The code for the original ngInclude-directive is way longer, so if you use animations in your application, c&p the original code and shoehorn the `$element.replaceWith() into that.

    var includeDirective = ['$http', '$templateCache', '$sce', '$compile',
                            function($http, $templateCache, $sce, $compile) {
        return {
            restrict: 'ECA',
            priority: 600,
            terminal: true,
            link: function(scope, $element, $attr) {
                scope.$watch($sce.parseAsResourceUrl($attr.src), function ngIncludeWatchAction(src) {    
                    if (src) {
                        $http.get(src, {cache: $templateCache}).success(function(response) {
                            var e =$compile(response)(scope);
                            $element.replaceWith(e);
                        });       
                    }
                }); 
            }
        };
    }];
    
    myApp.directive('ngInclude', includeDirective);
    

提交回复
热议问题