指令中的 template 和 templateUrl 之间的区别

Different between template and templateUrl in a directive

当我使用 angular 1.5.3 编码时。 这是代码:

app.js

var testApp = angular.module('test-app', ['plugin.template']);

testApp.run(function ($rootScope) {

});

createDirective('directiveOne');
createDirective('directiveTwo');
createDirective('directiveThree');

function createDirective(name) {
  testApp.directive(name, function () {
    return {
      template: '<div>Hello<div ng-transclude></div></div>',
      // templateUrl: 'template.html',
      transclude: true,
      replace: true,
      compile: function (element, attr) {
        console.log(name + '指令的compile...');
        return {
          post: function (iScope, iElm, iAttr, ctrl) {
            console.log(name + '指令的postlink...');
          },
          pre: function () {
            console.log(name + '指令的prelink...');
          }
        }
      }
    }
  });

}

插件-template.js

(function (app) {
  try {
    app = angular.module("plugin.template");
  }
  catch (err) {
    app = angular.module("plugin.template", []);
  }
  app.run(["$templateCache", function ($templateCache) {
    "use strict";

    $templateCache.put("template.html", "<div>hello<div ng-transclude></div></div>");
  }]);
})();

index.html

<!DOCTYPE html>
<html lang="zh" ng-app="test-app">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, minimum-scale=1.0,initial-scale=1, maximum-scale=1.0, user-scalable=no">
    <script src="../dist/js/angular/angular.js"></script>
    <script src="plugin-template.js"></script>
    <script src="app.js"></script>
</head>
<body>

<directive-one>
    <directive-two>
        <directive-three>

        </directive-three>
    </directive-two>
</directive-one>

</body>
</html>

在函数createDirective中,注释掉// templateUrl: 'template.html',时。

      template: '<div>Hello<div ng-transclude></div></div>',
      // templateUrl: 'template.html',
      transclude: true,
      replace: true,

这是日志:

directiveOne指令的compile...
directiveOne指令的prelink...
directiveTwo指令的compile...
directiveTwo指令的prelink...
directiveThree指令的compile...
directiveThree指令的prelink...
directiveThree指令的postlink...
directiveTwo指令的postlink...
directiveOne指令的postlink...

注释掉时// template: '<div>Hello<div ng-transclude></div></div>',

      // template: '<div>Hello<div ng-transclude></div></div>',
      templateUrl: 'template.html',
      transclude: true,
      replace: true,

这是日志:

directiveOne指令的compile...
directiveOne指令的prelink...
directiveOne指令的postlink...
directiveTwo指令的compile...
directiveTwo指令的prelink...
directiveTwo指令的postlink...
directiveThree指令的compile...
directiveThree指令的prelink...
directiveThree指令的postlink...

当全部注释掉时:

// template: '<div>Hello<div ng-transclude></div></div>',
// templateUrl: 'template.html',
// transclude: true,
// replace: true,  

这是日志:

directiveOne指令的compile...
directiveTwo指令的compile...
directiveThree指令的compile...
directiveOne指令的prelink...
directiveTwo指令的prelink...
directiveThree指令的prelink...
directiveThree指令的postlink...
directiveTwo指令的postlink...
directiveOne指令的postlink...

'compile', 'prelink','postlink' 的顺序在我注释掉上面的代码后发生了变化

为什么会这样? 你能解释一下 template 和 templateUrl 之间的区别,以及在指令中使用 transclude 和不使用 transclude 之间的区别吗? 非常感谢。

来自文档:

templateUrl

This is similar to template but the template is loaded from the specified URL, asynchronously.

Because template loading is asynchronous the compiler will suspend compilation of directives on that element for later when the template has been resolved. In the meantime it will continue to compile and link sibling and parent elements as though this element had not contained any directives.

The compiler does not suspend the entire compilation to wait for templates to be loaded because this would result in the whole app "stalling" until all templates are loaded asynchronously - even in the case when only one deeply nested directive has templateUrl.

— AngularJS Comprehensive Directive API Reference - templateUrl