自定义ngInclude:模板中的变量未替换

时间:2016-03-07 12:02:13

标签: javascript html angularjs angularjs-directive

我尝试创建加载自定义模板的指令,但如果自定义不存在,请加载默认模板。

这是我的代码:

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>

知道如何解决这个问题吗?我猜测它是因为&#34; ng-include =&#39; src&#39;&#34;,其中&#34; src&#34;没有被路径取代......如何解决?

修改

我试图把这个模板:

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

但是我收到了这个错误:

  

错误:[$ parse:syntax]   http://errors.angularjs.org/1.5.0/ $解析/语法P0 =%7B&安培; P1 =无效%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.src替换为scope.tmpSrc,现在ng-include值很好,但是我的html视图中的替换模板已被注释掉......为什么?

编辑3:

使用您的代码段,我想知道我需要做什么:

&#13;
&#13;
  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';
    }
  ]);
&#13;
<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>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分: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>