2016-03-07 51 views
0

我试图创建一个指令来加载自定义模板,但如果自定义不存在,请加载默认模板。自定义ngInclude:模板中的变量未被替换

这里是我的代码:

HTML:

<my-include src="path/to/template.html"></my-include> 

指令:

angular.module('app') 

    .directive("myInclude", function ($compile) { 
     return { 
      restrict: 'CAE', 
      replace: true, 
      scope: { 
       src: '@', 
      }, 
      link: function (scope, iElement, iAttrs, controller) { 
       scope.$on("$includeContentError", function (event, args) { 

        scope.src = args.replace('/custom', '').replace("'", ''); 
       }); 
       scope.$on("$includeContentLoaded", function (event, args) { 

        scope.src = args.replace("'", ''); 
       }); 
      }, 
      template: '<div class="include-container" ng-include="src"></div>' 
     }; 
    }) 
; 

我的问题是......我的模板不显示... 当我调试它时,它会转到该指令并替换src。但我得到的HTML如下:

<div class="include-container ng-scope" ng-include="src" src="path/to/template.html"><div class="main-information-content ng-scope"> 
</div> 

任何想法如何,我可以解决这个问题?我猜这是因为“ng-include ='src'”,其中“src”没有被路径替换......如何修复它?

编辑:

我试图把这个模板:

template: '<div class="include-container" ng-include="{{ src }}"></div>' 

,但我得到这个错误:

Error: [$parse:syntax] http://errors.angularjs.org/1.5.0/ $parse/syntax?p0=%7B&p1=invalid%20key&p2=2&p3=%7B%7Brc%20%7D%7D&p4=%7B%src%20%7D%7D

编辑2: 当我把这个作为模板:

template: '<div class="include-container" ng-include="tmpSrc"></div>' 

并替换scope.srcscope.tmpSrc,ng-include值现在是好的,但是在我的html视图中被替换的模板被注释掉了......为什么?

编辑3:

使用您的片段,这里是什么,我需要做的一个想法:

angular 
 
    .module('app', []) 
 
    .directive("myInclude", function($compile) { 
 
     return { 
 
     restrict: 'CAE', 
 
     replace: true, 
 
     scope: { 
 
      src: '@', 
 
     }, 
 
     link: function(scope, iElement, iAttrs, controller) { 
 
      scope.$on("$includeContentError", function() { 
 
      scope.src = 'error-template.html'; 
 
      }); 
 
      scope.$on("$includeContentLoaded", function(event, args) { 
 
      // No need to do anything - the content has loaded. 
 
      }); 
 
     }, 
 
     template: '<div class="include-container" ng-include="src"></div>' 
 
     }; 
 
    }) 
 

 
    .controller('mainController', ['$scope', '$http', 
 
    function($scope, $http) { 
 

 
     // Is the content loaded ? 
 
     $scope.state = 'loading'; 
 
    } 
 
    ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script> 
 

 
<div ng-app="app"> 
 
    <div> 
 
    This will show the correct template: 
 
    <my-include src="path/to/template.html"></my-include> 
 
    </div> 
 

 
    <div> 
 
    This will show an error template: 
 
    <div ng-controller="mainController as main"> 
 
     <my-include src="something/that/does/not/exist.html"></my-include> 
 
    </div> 
 
    </div> 
 

 
    <script type="text/ng-template" id="path/to/template.html"> 
 

 
    <h1>I want to display state : {{ state }}</h1> 
 
    </script> 
 
    <script type="text/ng-template" id="error-template.html"> 
 
    <h1>Hello from "error-template.html"</h1> 
 
    </script> 
 
</div>

+0

也尝试'compile'阶段这样做,而不是在'后link' – harishr

+0

我怎么能这样做?对不起,不是一个angularjs专家呢! – carndacier

回答

2

基本上你想要的是 “提升” ngInclude为了支持和错误回退,而不是创建一个新的范围(因为这可能会导致scope's prototypical inheritance,如this one的某些“错误”或this one等)。

我已经创建了一个这样做的指令。它加载通过src属性指定的自定义模板,并支持通过error-src属性指定的回退模板选项。

我不是这种方法的忠实粉丝,特别是如果你在模板中添加逻辑取决于它的父项。您应该将模板逻辑委托给专注和可重用的指令。这将有助于测试过程并隐藏实施细节。

angular 
 
     .module('app', []) 
 
     .controller('MainController', ['$scope', 
 
     function($scope) { 
 
      // Is the content loaded ? 
 
      $scope.state = 'loading'; 
 
     } 
 
     ]) 
 
     .directive('staticNgInclude', ['$compile', '$http', '$templateCache', 
 
     function($compile, $http, $templateCache) { 
 
      return { 
 
      link: function(scope, iElement, iAttrs) { 
 
       if (angular.isUndefined(iAttrs.src)) { 
 
       throw 'staticNgInclude requires the src attribute.' 
 
       } 
 

 
       $http 
 
       .get(iAttrs.src, { 
 
        cache: $templateCache 
 
       }).then(function(response) { 
 
        // Hooray, the template was found! 
 
        $compile(iElement.html(response.data).contents())(scope); 
 
       }, function() { 
 
        // Fetch the error template! 
 
        $http 
 
        .get(iAttrs.errorSrc || 'error-template.html', { 
 
         cache: $templateCache 
 
        }).then(function(response) { 
 
         $compile(iElement.html(response.data).contents())(scope); 
 
        }); 
 
       }); 
 
      }, 
 
      replace: false, 
 
      restrict: 'E' 
 
      }; 
 
     } 
 
     ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script> 
 

 
<div ng-app="app"> 
 
    <div ng-controller="MainController"> 
 
    This will show the correct template: 
 
    <static-ng-include src="path/to/template.html"></static-ng-include> 
 
    </div> 
 
    <div> 
 
    This will show an error template: 
 
    <static-ng-include src="something/that/does/not/exist.html"></static-ng-include> 
 
    </div> 
 
    <script type="text/ng-template" id="path/to/template.html"> 
 
    <h1>I want to display state : {{ state }}</h1> 
 
    </script> 
 
    <script type="text/ng-template" id="error-template.html"> 
 
    <h1>Hello from "error-template.html"</h1> 
 
    </script> 
 
</div>

+0

我已经试过了,但后来发现角度错误,我的模板仍然没有显示。我会用我得到的错误更新我的问题 – carndacier

+0

当然。让我们看看这个错误。 –

+0

我已经更新了我的问题,并收到了错误; – carndacier