停止在我的自定义元素指令上执行其他指令 [英] stop execution of other directive on my custom element directive
问题描述
我有一个自定义元素指令,例如如下图
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
并使用 priority
和 terminal
跳过它,那就是
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屋!