angular directive:动态切换两个模板

时间:2015-11-04 17:38:05

标签: javascript angularjs directive

我正在尝试创建一个名为availableTo的指令,它可以根据某些消息在两个不同的模板之间切换。例如,如果字段是带有input指令的ng-model,我首先需要使用<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。这似乎是我不可能完成的任务,但我想听听一些专家的意见。感谢

1 个答案:

答案 0 :(得分:3)

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>之间切换。