草庐IT

javascript - 当 Angular 指令的名称真的很重要时

coder 2023-08-09 原文

我刚刚遇到 Angular 的一个奇怪行为:

场景如下:

在注册表单中,我想检查电子邮件的唯一性(通过对服务器的 http 调用)。
因此,我创建了一个名为 emailUnique 的指令,其客户端代码为:

<form name="form" novalidate>
<!-- some other fields -->
<input name="email" type="email" ng-model="user.email" required email-unique/>
</form>

对于帖子的其余部分,假设用户正在键入:michael,这显然不是有效的邮件。

让我们看一下指令代码中有趣的部分,触发我感兴趣的行为:

angular.module('directives.emailUnique', [])
    .directive('emailUnique', function () {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, el, attrs, ctrl) {
                ctrl.$parsers.push(function (viewValue) {
                    console.log(viewValue);   //What do you expect here for viewValue? answer below
                });
            }
        };
    });

在给出答案之前,乍一看,答案在逻辑上应该是:

undefined 

为什么?因为:

  • 我们精确地定义了 type="email" 属性,而不仅仅是 type="text"
  • michael 不是有效的邮件。
  • Angular 的编译器应该符合经典的 HTML 行为。

经过测试,答案如预期的那样是undefined。我的完整指令的逻辑将基于此,并且整个工作正常。

现在,让我们重命名该指令:emailUnique 变为 somethingUnique
现在的客户:

<input name="email" type="email" ng-model="user.email" required something-unique/>

惊喜:console.log(viewValue) 现在显示:michael,而不是 undefined ...

显然,在这种情况下处理电子邮件字段时,名称以 email 开头会产生奇怪的效果。

我的问题很简单:有充分的理由吗?一个可能的错误?我可能误解了一些概念?

一些进一步的精度:

  • Angular's documentation关于带 Angular 电子邮件字段不提供一些可能会干扰 email-uniqueemail 属性。实际上,它是基于 type="email"
  • 无论表单的 novalidate 属性是否存在,我都遇到了同样的问题。

最佳答案

问题是指令的优先级。由于您依赖于添加解析器的时间,因此您需要设置指令的优先级 - 这将确保您需要的时间。

在您的演示中,somethingUnique 指令在验证添加到解析器列表之前运行(它最终位于 3 个解析器的中间)。而对于 emailUnique,它是在后面添加的。

将指令的优先级设置为大于 0 的值可确保它在 emailValidation 始终为您提供 undefined 后触发(来自 $compile docs 的注释:“后链接函数以相反的顺序运行”)。要确认这一点,您可以通过将其优先级设置为小于 0 来强制 emailUnique 失败。

所以这解决了问题:

.directive('somethingUnique', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        priority: 100,
        link: function (scope, el, attrs, ctrl) {
            ctrl.$parsers.push(function (viewValue) {
                console.log(viewValue);
            });
        }
    };
});

Updated plunker

更新名称问题: Angular 似乎按字母顺序处理具有相同优先级的指令。所以 homethingUnique 表现得像 emailUnique 因为两者都在 input 之前,而 jomehtingUnique 表现得像 somethingUnique - 输入后运行。

但是Angular's docs说:“具有相同优先级的指令的顺序未定义。”所以我们不能指望按字母顺序排列。

关于javascript - 当 Angular 指令的名称真的很重要时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20639972/

有关javascript - 当 Angular 指令的名称真的很重要时的更多相关文章

  1. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  2. ruby-on-rails - 应用程序的名称是否可以作为变量使用? - 2

    当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve

  3. ruby-on-rails - 如何从过时的 TZInfo 标识符中获取 Rails TimeZone 名称? - 2

    已经有一个问题回答了如何将“America/Los_Angeles”转换为“PacificTime(US&Canada)”。但是我想将“美国/太平洋”和其他过时的时区转换为RailsTimeZone。我无法在图书馆中找到任何可以帮助我完成此任务的东西。 最佳答案 来自RailsActiveSupport::TimeZonedocs:TheversionofTZInfobundledwithActiveSupportonlyincludesthedefinitionsnecessarytosupportthezonesdefinedb

  4. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  5. ruby - 解释为局部变量会覆盖方法名称吗? - 2

    如thisquestion,当在其自己的赋值中使用未定义的局部变量时,它的计算结果为nil。x=x#=>nil但是当局部变量的名称与现有的方法名称冲突时,就比较棘手了。为什么下面的最后一个示例返回nil?{}.instance_eval{a=keys}#=>[]{}.instance_eval{keys=self.keys}#=>[]{}.instance_eval{keys=keys}#=>nil 最佳答案 在Ruby中,因为可以在没有显式接收器和括号的情况下调用方法,所以在局部变量引用和无接收器无参数方法调用之间存在语法歧义:f

  6. ruby-on-rails - 如何让 Rails View 返回其关联的操作名称? - 2

    我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam

  7. ruby-on-rails - ActiveAdmin 自定义选择过滤器下拉名称 - 2

    对于用户模型,我有一个过滤器来检查用户的预订状态,该状态由整数值(0、1或2)表示。UserActiveAdmin索引页上的过滤器是通过以下代码实现的:filter:booking_status,as::select然而,这会导致下拉选项为0、1或2。当管理员用户从下拉列表中选择它们时,我更愿意自己将它们命名为“未完成”、“待定”和“已确认”之类的名称。有没有办法在不改变booking_status在模型中的表示方式的情况下做到这一点? 最佳答案 假设booking_status是模型中的枚举字段,您可以使用:过滤器:booking

  8. ruby-on-rails - 我真的需要在 Rails 中使用 csv gem 吗? - 2

    我的问题很简单:我是否必须在使用RubyonRails的类上require'csv'?如果我打开一个railsconsole并尝试使用CSVgem它可以工作,但我必须在文件中这样做吗? 最佳答案 CSVlibrary是ruby​​标准库的一部分;它不是gem(即第三方库)。与所有标准库(与核心库不同)一样,csv不会由ruby​​解释器自动加载。所以是的,在您的应用程序中某处您确实需要要求它:irb(main):001:0>CSVNameError:uninitializedconstantCSVfrom(irb):1from/Us

  9. ruby - Ruby 中 <=> 运算符的名称是什么?他们怎么调用它? - 2

    在Ruby中有运算符(operator)。在API中,他们没有命名它的名字,只是:Theclassmustdefinetheoperator...Comparableusestoimplementtheconventionalcomparison......theobjectsinthecollectionmustalsoimplementameaningfuloperator...它叫什么名字? 最佳答案 参见上面的@Tony。然而,它也被称为(俚语)“宇宙飞船运算符(operator)”。

  10. ruby - 将 Logstash 中的时间戳时区转换为输出索引名称 - 2

    在我的场景中,Logstash收到的系统日志行的“时间戳”是UTC,我们在Elasticsearch输出中使用事件“时间戳”:output{elasticsearch{embedded=>falsehost=>localhostport=>9200protocol=>httpcluster=>'elasticsearch'index=>"syslog-%{+YYYY.MM.dd}"}}我的问题是,在UTC午夜,Logstash在外时区(GMT-4=>America/Montreal)结束前将日志发送到不同的索引,并且索引在20小时(晚上8点)之后没有日志,因为“时间戳”是UTC。我们已

随机推荐