angular 指令:在两个模板之间动态切换

angular directive: switch between two templates dynamically

我正在尝试创建一个名为 availableTo 的指令,它可以根据某些消息在两个不同的模板之间切换。例如,如果该字段是带有 ng-model 指令的 input,我首先需要使用 <span> 标记将其更改为只读。到目前为止,我的代码可以将视图切换为只读,但我似乎无法将其切换回 input:

var directive = {
      restrict: 'A',
      require: '?ngModel',
      link: linkerFn,
      replace: true
    };

function linkerFn(scope, element, attrs, ngModelCtrl) {

        var clonedElement = angular.copy(element);
        var preOuterHTML = clonedElement[0].outerHTML; //this can save the <input> field html code

        scope.$on('mode_changed', function() {
          var curUserRole = userservices.getUserRole();

          if (attrs.availableTo == curUserRole) {
                var e = $compile(preOuterHTML)(scope);
                element.replaceWith(e);
          } else {
                var template = '<span>' + ngModelCtrl.$viewValue + '</span>';
                var e = $compile(template)(scope);
                element.replaceWith(e);
          }

        }); //scope.$on
    } //linkerFn

对于 input 字段:

  <input name="test1" class="form-control" ng-model="name" placeholder="Name 1" available-to="ADMIN"/>

我还注意到,一旦我更改了上面 else 块中的模板,元素就会重新呈现,并且 preOuterHTML 不再包含原始元素 html .这对我来说似乎是不可能完成的任务,但我想听听一些专家的意见。谢谢

element.replaceWith(e); 不要那样做。在 Angular 中,如果您发现自己试图直接修改 DOM,那么您显然做错了。你得坐下来让 Angular 完成工作。

如果您需要替换指令的整个模板,一个相当简单的方法是使用 ng-include 和一个包含所需条件 templateUrl 的范围变量,例如

var directive = {
  // ...
  template: '<div ng-include="myTemplateUrl"></div>',
  link: function(scope, el) {
    if (/* whatever */) {
      scope.myTemplateUrl="templates/foo.html";
    } else {
      //...etc
    }
  },
};

(这确实会向树添加一个额外的 DOM 节点,但这通常是无害的。)

听起来您的情况可能不需要走那么远;模板中的一个简单 ng-if 可能足以在只读 <span><input>.

之间切换