通过定义自定义角度指令将HTML输入字段更改为标签

时间:2015-12-23 07:24:04

标签: angularjs angularjs-directive

我有很多输入,textarea并在某些页面上选择(角度模板)。 我想重新定义“输入”指令,以便从 localStorage 获取类似ViewMode = true的值,并将所有输入转换为标签。如果我更改ViewMode然后页面刷新输入应该正常运行。

但我不想在任何角度模板上编辑任何输入标记。

表示我想覆盖input,textarea并选择作为我自己的angular指令。

我无法开始。我应该从哪里开始? (我有使用新名称的自定义指令的经验,但没有任何令人兴奋的HTML标记名称)

注意:我不想使用readonly(使用正确的样式),因为它需要编辑所有输入标记。不仅我有自定义指令与隔离范围,所以我需要将ViewMode值传递给所有自定义指令。如果用户按CTRL + A内容只读字段未被选中,则更多。

我正在寻找如下解决方案

ViewButtonClickEvent () {
   set localStorage.viewMode = true;
   callExistingEditMethod();
}

EditButtonClickEvent () {
  set localStorage.viewMode = false;
  callExistingEditMethod();
}

editPagesModule.directive('input', {
    if(localStorage.viewMode != true)
     //Keep all existing functionality with ng-model
    }
    else {
      //replace input with span or label.
    }
})

1 个答案:

答案 0 :(得分:3)

您可以创建名为inputselecttextarea的指令,这些指令会自动编译而无需更改现有标记。

工作示例:JSFiddle& Plunker

它看起来像这样:

angular.module('myApp', [])
  .directive('input', inputDirective)
  .directive('select', inputDirective)
  .directive('textarea', inputDirective)
  .factory('$editMode', editModeFactory)
;

inputDirective.$inject = ['$editMode'];
function inputDirective($editMode) {
  return {
    link: postLink
  };

  function postLink(scope, iElement, iAttr) {
    scope.$watch($editMode.get, function(edit) {
      if (iElement[0].nodeName === 'SELECT') {
        if (edit === 'true') iElement.removeAttr('disabled');
        else iElement.attr('disabled', true);
      }
      else {
        if (edit === 'true') iElement.removeAttr('readonly');
        else iElement.attr('readonly', true);
      }
    });
  }
}

editModeFactory.$inject = ['$window'];
function editModeFactory($window) {
  return {
    get: function() {
      return $window.localStorage.getItem('editMode');
    },
    set: function(value) {
      $window.localStorage.setItem('editMode', value);
    }
  };
}

我确实使用readonly属性(disabled用于选择),因为我能想到的唯一其他选项是用div之类的东西替换整个输入元素。您还必须缓存原始元素,以便稍后可以恢复...并且执行此类操作会破坏绑定,因此您每次都必须重新编译每个输入。这似乎是一个可怕的想法。