Angular指令动态模板不使用绑定

时间:2016-11-07 16:17:51

标签: javascript angularjs

这是一个真实问题的简化版本,但我想了解发生了什么以及如何解决它。我有一个指令,应该加载不同的模板deppending正在绑定它的参数。



var app = angular.module('my_app', [])
  .controller('controller', Controller)
  .directive('dirTwo', DirTwo);

function Controller() {
  var este = this;
  this.list = ["number", "text", "text"];
  this.change = function() {
    this.list = this.list.reverse();
  }
}

function DirTwo() {
  return {
    restrict: 'E',
    //template: ' Name: {{name}}{{type}}',
    template: my_template,
    scope: {
      type: "="
    },
    link: function($scope) {
      $scope.name = "Pepito";
      console.log("scope type: " + $scope.type);
    }
  }
}
var my_template = function(elem, attrs, $scope) {
  console.log("template type: " + attrs.type);
  switch (attrs.type) {
    case 'number':
      return '<a href="#">{{type}}</a>';
      break;
    default:
      return ' ---- '
      break;
  }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<div class="app" ng-app="my_app" ng-controller="controller as App">
  <p>{{App.list}}
    <button ng-click="App.change()">Reverse</button>
  </p>
  <dir-two ng-repeat="item in App.list track by $index" type="item"></dir-two>
</div>
&#13;
&#13;
&#13;

模板功能中的日志打印单词item而不是numbertext。如何修复它以正确加载模板?

1 个答案:

答案 0 :(得分:1)

不幸的是,没有办法像这样使用template,因为模板解析发生在编译阶段之前,type将假设范围值。要根据范围值更改指令的模板,您必须观察该值并在更改指令元素时重新编译该指令元素。它将使用新模板完全重新编译该指令,但具有相同的范围。你也可以这样做一次(即没有$watch)。

以下代码段实现了此解决方案。

&#13;
&#13;
var app = angular.module('my_app', [])
  .controller('controller', Controller)
  .directive('dirTwo', DirTwo);

function Controller() {
  var este = this;
  this.list = ["number", "text", "text"];
  this.change = function() {
    this.list = this.list.reverse();
  }
}

function DirTwo($compile) {
  return {
    restrict: 'E',
    template: '',
    scope: {
      type: "="
    },
    link: function(scope, element) {
      
      var tmplScope;
      
      scope.name = "Pepito";
      scope.$watch('type', function(type) {

        if (tmplScope) tmplScope.$destroy();

        tmplScope = scope.$new();

        element.html(getTemplate(type));
        $compile(element.contents())(tmplScope);
      });
    }
  }
}
var getTemplate = function(type) {

  switch (type) {
    case 'number':
      return '<a href="#">{{type}}</a>';
      break;
    default:
      return ' ---- '
      break;
  }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>
<div class="app" ng-app="my_app" ng-controller="controller as App">
  <p>{{App.list}}
    <button ng-click="App.change()">Reverse</button>
  </p>
  <dir-two ng-repeat="item in App.list track by $index" type="item"></dir-two>
</div>
&#13;
&#13;
&#13;

  

更新注意:我已经更改了实际的编译系统,以便在每次编译时创建一个新的子范围,并在重新编译时销毁此子范围以防止添加新的{{ 1}}重新编译它而不丢弃以前的。感谢@georgeawg,他在评论中警告过这个问题。