【问题标题】:AngularJS: How to create a directive that adds/removes itself from DOM when needed?AngularJS:如何创建在需要时从 DOM 中添加/删除自身的指令?
【发布时间】:2016-06-19 11:04:35
【问题描述】:

如果我有一个看起来像这样的自定义模式指令:

return {
  restirct: 'E',
  templateUrl: 'modal.html',
  scope: {
    modalContent: "=",
    modalOpen: "="
  }
}

和html:

<ng-modal modal-content="content" modal-open"active"></ng-modal>

如何确保模态在 DOM 关闭时不存在于 DOM 中,一旦打开它就会将其自身插入 DOM?我必须将指令插入到 html 中,否则指令将不起作用,但这意味着当我运行应用程序时,即使它没有打开,模式也已经存在于 html 中。

我创建了一个到目前为止here 的 plunker,但它只使用 css 类隐藏/显示模态,而不是完全删除它

编辑:

我创建了另一个版本here,它实际上在 DOM 中添加/删除了指令。它基于this 文章,但它需要在指令和外部控制器之间拆分添加/删除指令的逻辑(外部控制器处理添加元素,指令处理删除)。我希望指令处理所有事情,这可能吗?

【问题讨论】:

  • 我曾经使用类似于 BootstrapUI $modal 服务的 API 创建了非常简单的模态服务(注意:不是指令)。检查它(out)[github.com/dfsq/angular-google-tasks/blob/master/app/components/…。它正确地创建和删除模态。
  • 为什么不使用ng-if 指令? ngIf 指令根据表达式删除或重新创建 DOM 树的一部分。 docs.angularjs.org/api/ng/directive/ngIf
  • @georgeawg 这只适用于我将 ng-if 放在模板内的内容上,如果我将 ng-if 放在 &lt;ng-modal&gt; 指令上,那么该指令将根本不起作用。我还希望能够控制插入/附加指令的位置,这是 ng-if 无法实现的。
  • 您为解决问题做了哪些工作?到目前为止,您遇到了什么困难?
  • @georgeawg 用我目前所拥有的内容编辑了原始问题。

标签: javascript angularjs dom


【解决方案1】:

这是你想要的吗?我用一个 div 包装了模板的内容,以便更容易在一个变量中抓取整个块。然后我根据您是要显示还是隐藏它来添加和删除该 div。

我不相信您可以删除&lt;ng-modal&gt; 元素,但这至少会删除其中的所有内容...

http://plnkr.co/edit/Lr77FuGwcPbojgf3fHuW?p=preview

html

<div>
  <div class="modal hide">
    <h4>{{modalContent.title}}</h4>
    <p>{{modalContent.text}}</p>
    <button ng-click="close()">Close Modal</button>
  </div>

  <div class="modal-overlay"></div>
</div>

js

var ModalDirective = function() {
  return {
    restirct: 'E',
    templateUrl: 'modal.html',
    scope: {
      modalContent: "=",
      modalOpen: "="
    },
    link: function(scope, element, attrs) {
      var modalElements = element.children()[0];
      console.log(element);

      function addModal() {
        console.log('Opening modal');
        element.addClass('open');
        //add the modal elements back into the directive
        if (modalElements) {
          //should be 0
          console.log('Element child count before add', element.children().length);
          element[0].appendChild(modalElements);
           //should be 1
           console.log('Element child count after add', element.children().length);
        }
      }

      function removeModal() {
        element.removeClass('open');
        console.log('Closing modal');
        if (modalElements) {
          //remove the modal elements from the directive
           //should be 1
          console.log('Element child count before remove', element.children().length);
          element[0].removeChild(modalElements);
          //should be 0
          console.log('Element child count after remove', element.children().length);
        }
      }

      scope.$watch('modalOpen', function(newVal, oldVal) {

        if (newVal) {
          addModal();
        } else {
          removeModal();
        }

      });

      scope.close = function() {
        scope.modalOpen = false;
      }
    }
  }
}

【讨论】:

  • 我得出了同样的结论,似乎不依赖外部控制器就无法删除 ng-modal 标签。我最终得到的解决方案与您的方法类似,只是我使用 $templateCache 服务来存储 modalElements 的 html,而不是依赖它已经存在。
【解决方案2】:

使用 jquery:

$(element).remove()

没有jquery:

element.html("")
element.remove();
element.empty();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-22
    • 2017-03-23
    • 2017-05-08
    • 2019-10-04
    • 2015-06-06
    • 2016-10-08
    • 1970-01-01
    相关资源
    最近更新 更多