【问题标题】:angular: how to nest templates inside <pre> tags?角度:如何在 <pre> 标签内嵌套模板?
【发布时间】:2016-03-13 20:51:47
【问题描述】:

有谁知道我如何在“pre”标签中进行 ng-include ?用例是我有一个包含一些代码块的网站,其中一些代码块包含我想移动到单独部分的公共代码。示例:

<pre>
    My page-specific code....
    <ng-include src="'partials/common-code.html'"></ng-include>
</pre>

不用说,这是行不通的,因为 ng-include 标记字面上出现在输出中...

【问题讨论】:

    标签: html angularjs angularjs-ng-include pre


    【解决方案1】:

    我能够根据您使用顶级自定义 pre 指令的想法解决它,但使用不同的 impl:我正在运行 BFS 算法,每个摘要循环我尝试编译任何直接子 pre-包括。每次迭代我都会等到包含子项计数为零,然后再检查是否需要另一个循环(使用 scope.$watch)。完成后,我编译整个 my-pre 以解析任何 {{xxxx}} 并将其转换为 pre。 Working plunkr

    // simulate a 3d party highligther (tested with HLJS)
    .directive('myHighlighter', function($compile, $timeout) {
          return {
            restrict: 'E',
            controller: function() {},
            link: function(scope, element, attrs, controller) {
              // wait for the end of the digest:
              $timeout(function() {
              $(element).replaceWith($('<pre>' + element.text() + '</pre>'));
             });
            }
          }
    })
    
    // myPre will conert itself to the custom highlighter once done compiling:
    .directive('myPre', function($compile, $timeout) {
          return {
            restrict: 'E',
            controller: function() {},
            link: { 
              pre: function(scope, element, attrs, controller) {
              // limit the total inclusions allowed to avoid loops:
              scope.it = 100;
              // count inclusions:
              scope.incCount = 0;
    
                scope.$watch('incCount', function(newVal, oldVal, scope) {
                  if (oldVal !== newVal && newVal === 0) {
                      // watch the include tag count. When it's zero,
                      // see if we need another BFS pass for sub-children:
                    var children = $('pre-include', element).length;
                  if (children !== 0) {
                    $compile(element)(scope);
                  } else {
                      // If not, build the highlighter and we're done:
                    var e2 = $('<my-highlighter>' + element.html() + '</my-highlighter>');
                    $(element).replaceWith(e2);
                    $compile(e2)(scope);
                  }
                  }
                }); 
              },
              post: function(scope, element, attrs, controller) { 
              }
            }
          }
    })
    
    .directive('preInclude', function($templateRequest, $compile) {
      return {
        link: { 
          pre: function(scope, element, attrs, myPre) {
              scope.incCount++;
          }, 
          post: function(scope, element, attrs, myPre, transclude) {
            scope.it--;
            if (scope.it <= 0) {
              console.log("max iterations reached, stopping");
              return;
            }
            // enqueue the inclusion in the BFS queue:
            $templateRequest(attrs.src).then(function(data) {
              element.replaceWith(data);
              scope.incCount--;
            });
          }
        }
      };
    })
    

    【讨论】:

      【解决方案2】:

      您可以使用两个指令:一个是一种 ngInclude,另一个等待第一个加载内容并用 pre (http://plnkr.co/edit/fPy4M0ZK94erF31EeObE) 替换自己:

      module.directive('myPre', function() {
        return {
          controller: function() {},
          restrict: 'E',
          link: function(scope, element, attrs, controller) {
            controller.checkContent = function() {
              if (!element.children().length) {
                element.replaceWith('<pre>' + element.text() + '</pre>');
              }
            }
          }
        }
      })
      .directive('myPreTemplate', function($http) {
        return {
          require: '^myPre',
          restrict: 'E',
          link: function(scope, element, attrs, myPre) {
            $http.get(attrs.src).then(function(res) {
              element.replaceWith(res.data);
              myPre.checkContent();
            });
          }
        }
      });
      

      你可以像这里一样使用它:

      <my-pre>
        Code here...
        <my-pre-template src="common.html"></my-pre-template>
        ...and here...
        <my-pre-template src="common.html"></my-pre-template>
        ...and here again
      </my-pre>
      

      编辑:渲染普通模板的内容,最好的方法是使用mustacheplunker updated):

      ...
      $http.get(attrs.src).then(function(res) {
        var rendered = Mustache.render(res, scope);
        element.replaceWith(rendered);
        myPre.checkContent();
      });
      ...
      

      【讨论】:

      • 谢谢,我正在尝试测试您的代码,但我有一个问题:我希望 common.html 也是一个模板。但是,上面的代码不会将 common.html 中的任何 {{xxx}} 标记绑定到范围。我该如何解决?
      • 如果我错了请纠正我,但是 mustache 会渲染模板,但是,如果公共模板还包含嵌套在其中的 ,则 mustache 将无济于事。对吗?
      • 不,不会的。如果事情变得太复杂,我会用模板引擎静态地做到这一点
      • 我可以使用 $compile 在 my-pre-template 中解析 {{xx}} ......但是,如果我将另一个 my-pre-template 放入 common 中。 html 文件,我得到一个错误,内部 my-pre-template 无法编译,因为它需要 myPre 控制器...我认为它会找到一个,因为页面最终是如何构建的(即 my-pre 在顶层)。 ..
      • 使用 BFS 解决,在下方添加了新答案 + plunkr
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      • 2020-02-29
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      相关资源
      最近更新 更多