在角指令输入包装 [英] wrapping inputs in directives in angular

查看:110
本文介绍了在角指令输入包装的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有想法来包装投入定制指令,以保证通过我的网站一致的外观和行为。我也想换引导UI的日期选择器和下拉式。此外,该指令应该处理验证和显示工具提示。

I had the idea to wrap inputs into custom directives to guarantee a consistent look and behavior through out my site. I also want to wrap bootstrap ui's datepicker and dropdown. Also, the directive should handle validation and display tooltips.

中的HTML应该是这个样子:

The HTML should look something like this:

<my-input required max-length='5' model='text' placeholder='text' name='text'/>

<my-datepicker required model='start' placeholder='start' name='start'/>

在我想创建一个DOM结构类似指令:

in the directives i want to create a dom structure like:

<div>
 <div>..</div> //display validation in here
 <div>..</div> //add button to toggle datepicker (or other stuff) in here
 <div>..</div> //add input field in here
</div>

我想尽各种办法来实现这一点,但总是遇到一些权衡传来:

I tried various ways to achieve this but always came across some tradeoffs:


  1. 使用transclude并更换插入输入到指令DOM结构(在这种情况下,该指令将在上面的例子中被限制为A不E等)等。这里的问题是,有我想要添加在日期选择器的情况下,自定义属性来访问transcluded元素没有简单的方法。我可以使用transclude功能,然后重新编译链接功能模板,但这似乎对这个任务有点复杂。这也导致与transcluded范围和肘节状态为日期选择器(一个是在指示范围,在transcluded范围以外)。

  1. using transclude and replace to insert the input into the directives dom structure (in this case the directive would be restricted to 'A' not 'E' like in the example above). The problem here is, that there is no easy way to access the transcluded element as I want to add custom attributes in case of datepicker. I could use the transclude function and then recompile the template in the link function, but this seems a bit complex for this task. This also leads to problems with the transcluded scope and the toggle state for the datepicker (one is in the directives scope, the other in the transcluded scope).

只能更换。在这种情况下,所有的属性被施加到最外面的div(即使我生成在编译函数的模板DOM结构)。如果我只使用了输入作为模板,然后在属性上的投入,但我需要生成链接功能模板的然后重新编译它。据我了解的角度相模式,我想,以避免重新编译和改变链接功能模板的DOM(虽然我见过很多人在做这个)。

using replace only. In this case, all attributes are applied to the outermost div (even if I generate the template dom structure in the compile function). If I use just the input as template, then the attributes are on the input, but I need to generate the template in the link function an then recompile it. As far as I understand the phase model of angular, I would like to avoid recompiling and changing the template dom in the link function (although I've seen many people doing this).

目前我与第二种方式工作,并产生了链接功能模板,但我想知道,如果有人有一些更好的想法!

Currently I'm working with the second approach and generating the template in the link function, but I was wondering if someone had some better ideas!

推荐答案

这就是我认为是这样做的正确方法。就像我OP希望能够使用一个属性指令为包装的输入。但我也希望它一起工作 NG-如果和这种无漏水的任何元素。由于@jantimon指出的那样,如果你不清理您的包装元素,他们将NG-如果破坏了原有的元素之后流连忘返。

Here's what I believe is the proper way to do this. Like the OP I wanted to be able to use an attribute directive to wrapper an input. But I also wanted it to work with ng-if and such without leaking any elements. As @jantimon pointed out, if you don't cleanup your wrapper elements they will linger after ng-if destroys the original element.

app.directive("checkboxWrapper", [function() {
    return {
      restrict: "A",
      link: function(scope, element, attrs, ctrl, transclude) {
        var wrapper = angular.element('<div class="wrapper">This input is wrappered</div>');

        element.after(wrapper);
        wrapper.prepend(element);

        scope.$on("$destroy", function() {
          wrapper.after(element);
          wrapper.remove();
        });
      }
    };
  }
]);

和这里是一个plunker 你可以玩。

重要提示范围 VS 元素 $摧毁。你必须把你清理在范围。在$($消灭)而不是 element.on($消灭)(这是我最初尝试)。如果你这样做了后者(要素),那么一个ngIf结束注释标记将得到泄露。这是由于角的ngIf如何去有关清理结束注释标记时,它的falsey逻辑。把你的指令的清理code的范围内$摧毁你可以把后面的DOM就像是你wrappered输入等等NG-如果的清理code是幸福的了。到时候element.on($消灭)被调用,它是太晚了NG-如果falsey流动解开原始元素而不会导致注释标记泄漏。

IMPORTANT: scope vs element $destroy. You must put your cleanup in scope.$on("$destroy") and not in element.on("$destroy") (which is what I was originally attempting). If you do it in the latter (element) then an "ngIf end" comment tag will get leaked. This is due to how Angular's ngIf goes about cleaning up its end comment tag when it does its falsey logic. By putting your directive's cleanup code in the scope $destroy you can put the DOM back like it was before you wrappered the input and so ng-if's cleanup code is happy. By the time element.on("$destroy") is called, it is too late in the ng-if falsey flow to unwrap the original element without causing a comment tag leak.

这篇关于在角指令输入包装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆