动态添加指令时不调用AngularJS $解析器

时间:2018-01-05 09:11:19

标签: angularjs angularjs-directive

所以我想要实现的是能够通过另一个指令添加包含解析器的指令。 当直接在html元素上添加解析器指令时,它完全正常。我目前使用的解析器指令:

.directive('parseTest', [
    function () {
        return {
            restrict: 'A',
            require: ['ngModel'],
            link: {
                post: function (scope, element, attributes, ctrls) {
                    var controller = ctrls[0];
                    controller.$parsers.unshift(function (value) {
                        var result = value.toLowerCase();
                        controller.$setViewValue(value);
                        controller.$render();

                        return result;
                    })
                }
            }
        }
    }
])

现在,当我通过另一个指令添加此指令时,解析器永远不会被奇怪地调用。生成parsetest指令的指令:

.directive('generateTest', ['$compile',
    function ($compile) {
        return {
            restrict: 'A',
            compile: function (elem, attrs) {

                elem.attr('parse-test', '');
                elem.removeAttr('generate-test');
                var linkFn = $compile(elem);
                return function (scope, element, attr) {
                    linkFn(scope);
                }
            }               
        }
    }
])

以下工作正常:

<input class="form-control col-sm-6" ng-model="model.parsetest" parse-test/>

以下不起作用(生成的结果html相同)

<input class="form-control col-sm-6" ng-model="model.generateTest" generate-test />

所以我的问题是如何在动态添加指令时让解析器工作?

注意,我已经尝试过针对this question的类似问题的解决方案,但这对我不起作用。

编辑:Here is a plnkr that demonstrates the issue,两个字段都应用了parse-test指令,该指令应该使模型中的值小写,但它仅适用于未动态添加的那个,如控制台日志中所示

1 个答案:

答案 0 :(得分:0)

所以我找到了解决方案,所以对于那些偶然发现同一问题的人来说。

必须对生成包含解析器或格式化程序的指令的指令进行2次小的更改。 首先将指令的优先级设置为高于或等于1的数字。其次将终端设置为true。这两个设置似乎解决了这个问题。 问题可能在于嵌套指令的默认执行使得解析器和格式化程序稍微插入到后期,这就是为什么我们需要确保指令首先在其他任何东西之前生成。

这只是假设它为什么起作用的假设,如果其他人有解释那将是伟大的:)

对于代码,生成另一个指令的指令应该类似于:

directive('generateTest', ['$compile',
    function ($compile) {
        return {
            restrict: 'A',
            terminal: true,
            priority: 1,
            compile: function (elem, attrs) {

                attrs.$set('parseTest', '');
                attrs.$set('generateTest', undefined);
                var linkFn = $compile(elem);
                return function (scope, element, attr) {
                    linkFn(scope);
                }
            }               
        }
    }
])