停止在我的自定义元素指令上执行其他指令 [英] stop execution of other directive on my custom element directive

查看:22
本文介绍了停止在我的自定义元素指令上执行其他指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义元素指令,例如如下图

i have a custom element directive e.g. like below

  <my-wrapper ng-model="values.abc" unique-check="" list="list" prop="name"> </my-wrapper>

此指令确实需要 ng-model,稍后将在内部输入标签上设置

This directive does require ng-model which is later being set on the inner input tag

  <input type="text" name="myfield" ng-model="'+attrs.ngModel+'"/>

发生的问题是,当我检查控制台时,我可以看到指令上的 ng-model 与输入标签上的 ng-model 不同.

the problem happening is when I check console I can see ng-model on directive is not same as ng-model on input tag.

如何确保外部标签上的 ng-model 没有被创建,并且它只在我的指令中创建一次.

How can I make sure that the ng-model on outer tag is not created and its created only once inside my directive.

我的指令代码如下

app.directive("myWrapper", function(){

  var templateFn = function(element, attrs){
    return '<div ng-form="myform">'+
          '<input type="text" name="myfield" ng-model="'+attrs.ngModel+'"/>'+
          '<span>(inside directive) : isDuplicate:{{myform.myfield.$error.isDuplicate}}</span>'
          '</div>';
  }

  return {
    restrict :'E',
    template : templateFn,
    require: 'ngModel',
    scope: true
  }
});

请注意,以上只是我的指令的缩短版本,我保留 scope: true 是因为整体方案的要求.

Please note that above is just a shortened version of my directive, and I have keep scope: true because of requirement in the overall scenario.

如果不清楚我在说什么,请查看THIS PLUNKER

If its not clear what I am talking about, please checkout the console of THIS PLUNKER

我尝试了使用 terminal : true 和/或 priority : 1001 的解决方案,以便 ng-model 不是在指令 html 上创建,而是仅在输入标签上创建,但是他们都没有工作.

I tried solutions with terminal : true and/or priority : 1001 so that the ng-model is not created on the directive html but only on input tag, but none of them worked.

是的,一种解决方案可以是用指令中的 my-model 替换 ng-model,然后在输入标签上再次将其添加为 ng-model,但随后它在我的应用程序中几乎有 1000 多个地方使用,所以真的不喜欢更换它.

yes, one solution can be to replace ng-model with lets say my-model on the directive and then again add it as ng-model on input tag, but then its being used at almost 1000s of places in my app, so really wont like to replace it as such.

解决此问题的任何其他方法.

any other way to solve this problem.

推荐答案

您可以尝试使用嵌入.与其尝试突破标准 AngularJS 编译的困难部分,不如将结构更改为:

You could try using transclusion. Instead of trying to do the hard part of breaking through standard AngularJS compilation, you could just change your structure to something like:

<my-wrapper>
    <input name="..." ng-model="...">
</my-wrapper>

并使您的指令将包装器扩展到您的模板中,其中包含嵌入的输入.(请参阅 <中的 transclude 选项code>$compile 文档.)这也会提高模板的可读性.

and make your directive expand the wrapper into your template with transcluded input inside it. (See the transclude option in $compile documentation.) This would increase readability of your templates as well.

或者,如果你需要你的指令生成复杂的内容(多个输入等),所有内容都封装并绑定到单个 ng-model,你可以保留 ng-model 它在哪里并使您的指令完全封装.我的意思是这样的:

Alternatively, if you need your directive to generate complex content (multiple inputs, etc.) all encapsulated and bound to that single ng-model, you could leave the ng-model where it is and make your directive completely encapsulated. By this I mean something like:

.directive('myComplexField', function () {
    return {
        scope: {},
        require: 'ngModel',
        link: function ($scope, $element, $attrs, ngModelCtrl) {
            ngModelCtrl.$formatters.push(function (modelValue) {
                // ... (update your isolated model based on external model change)
            });
            ngModelCtrl.$parsers.push(function (viewValue) {
                // ... (update external model based on your isolated model)
            });
            $scope.$watch('... (properties of your isolated model)', function () {
                // force sync (parser code above will take care of setting the real value)
                ngModelCtrl.$setViewValue(!ngModelCtrl.$viewValue);
            });
        }
    };
})

(参见 ngModelController文档).您只需要注意不要在 $parser$formatter 之间创建无限循环.

(see ngModelController documentation). You just need to be careful not to create an infinite loop between your $parser and $formatter.

如果您真的很想在包装器上留下 ng-model 并使用 priorityterminal 跳过它,那就是 非常简单:

If you're really dead set on leaving ng-model on your wrapper and skipping it using priority and terminal, it's pretty simple:

.directive('foo', function ($compile, $timeout) {
    return {
        restrict: 'E',
        priority: 2,  // ngModel priority is 1 (see the docs)
        terminal: true,
        link: function ($scope, $element) {
            $compile($element, undefined, 1)($scope);  // compiles priority *lower than 1*
        }
    };
}

应该尽可能避免这种方法,因为它有许多明显的缺点,但没有真正的优点.

This approach should be avoided if at all possible, because it has many apparent downsides and no real upside.

这篇关于停止在我的自定义元素指令上执行其他指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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