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

 N021039 发布于 2023-02-09 18:56

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

这是场景:

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

对于帖子的其余部分,让我们假设用户正在输入: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.
客户现在:


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

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

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

一些进一步的精确:

该角的文档有关的电子邮件场角不存在一些email可能干扰属性email-unique.实际上,它是基于type="email"

无论表单的novalidate属性是否存在,我都遇到了同样的问题.

KayakDave.. 5

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

在您的演示中,somethingUnique指令在验证添加到解析器列表之前运行(它最终在3个解析器的中间).而emailUnique它之后又添加了.

将指令的优先级设置为大于0的值确保它在emailValidation之后undefined始终触发(从$ compile文档中注意到:"post-link函数以相反的顺序运行").要确认这一点,您可以emailUnique通过将其优先级设置为小于0的值来强制失败.

所以这解决了这个问题:

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

更新了plunker

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

但是Angular的文档说:"具有相同优先级的指令的顺序是不确定的." 所以我们不能指望按字母顺序排列.

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

    在您的演示中,somethingUnique指令在验证添加到解析器列表之前运行(它最终在3个解析器的中间).而emailUnique它之后又添加了.

    将指令的优先级设置为大于0的值确保它在emailValidation之后undefined始终触发(从$ compile文档中注意到:"post-link函数以相反的顺序运行").要确认这一点,您可以emailUnique通过将其优先级设置为小于0的值来强制失败.

    所以这解决了这个问题:

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

    更新了plunker

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

    但是Angular的文档说:"具有相同优先级的指令的顺序是不确定的." 所以我们不能指望按字母顺序排列.

    2023-02-09 18:58 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有