更新1:添加更多细节。
更新 2:添加了 plunker 代码以重现问题。请参阅下面的链接。
更新 3:我在 github 上收到了 Angular 团队的回复。在这里检查。
更新 4:应 AngularJS 团队的要求在 github 上发布更新。此外,我之前添加的建议解决方案结果证明它正在创建一个新的视觉问题。请参阅下面的详细信息。
更新 5:从 Angular 团队获得另一个反馈。我认为我们已经接近找到解决方案的 80%。
我在我的项目中实现了Angular UI datepicker,过了一会儿,我注意到当我打开弹出框并单击月份更改为另一个月份时,另一个弹出窗口会显示在现有弹出窗口的顶部。请参阅下面的快照以获取更多详细信息:
最初,当我单击月份时,当前弹出窗口应该消失,并且应该显示另一个弹出窗口以选择新月份。
但是,当我在该月单击两次(下面以黄色突出显示)时,弹出窗口将消失,并且可以正常工作。但是,在我选择了一个日期之后,问题就会再次出现。
我正在使用来自 angular ui datepicker 官方演示网站的相同示例代码。在下面找到相关网站和 plunker 代码:
http://angular-ui.github.io/bootstrap/versioned-docs/1.3.3/#/datepickerPopup http://plnkr.co/edit/lEgJ9eC9SzBWsgVhhQkq?p=preview
我的代码与上面 plunker 示例中的代码完全相同。唯一的区别是我使用$compile
服务来动态添加必填字段验证。
经过广泛的故障排除后,发现该$compile()
服务会导致此行为。我做了一些研究,发现该$compile
服务还会导致下拉列表或select
元素中的重复项。我使用了建议的解决方法,它奏效了。请参见下面的代码:
$compile(child)(elmScope, function (clone) {
angular.element(child).after(clone);
angular.element(child).remove();
});
我使用的原因是在这里$compile
使用这种方法将动态验证规则从 DB 添加到元素。
在我得到github 上 Angular 团队的回复后,我发现他们提出了这个修复建议:
.directive('checkIfRequired', ['$compile', function ($compile) {
return {
priority: 1000,
terminal: true,
/*require: '?ngModel',*/
//JIRA: NE-2535 - inject the current 'ngForm' controller with this directive
// This is required to add automatice error message when the Form Field is invalid.
require: '?^form',
link: function (scope, el, attrs, ngForm) {
el.removeAttr('check-if-required');
el.attr('ng-required', 'true');
$compile(el, 1000)(scope);
}
};
}]);
当我尝试应用建议的修复程序时,我遇到了大量错误。似乎当使用terminal=true
then 时,'ng-init' 下的内部元素中的所有代码都没有执行。我注意到许多范围变量变得“未定义”。
这是github上试图找到解决方案的最后更新。请参见下面的代码:
app.directive('checkIfRequired', ['$compile', '$timeout', function ($compile, $timeout) {
return {
priority: 2000,
terminal: true,
/*link: function (scope, el, attrs) {
el.removeAttr('check-if-required');
var children = $(':input', el);
children.each(function(key, child) {
if (child && child.id === 'test_me') {
angular.element(child).attr('ng-required', 'true');
}
});
$compile(children)(scope);
},*/
compile: function (el, attrs) {
el.removeAttr('check-if-required');
var children = $(':input', el);
children.each(function(key, child) {
if (child && child.id === 'test_me') {
angular.element(child).attr('ng-required', 'true');
}
});
var compiled = $compile(children, null, 2000);
return function( scope ) {
compiled( scope );
};
}
};
}]);
感谢您在我的项目中以正确的方式应用修复程序的帮助。在此处查看代码的相关部分。
我之前发布了一个解决方案,但后来我删除了它。后来我注意到它引起了一个有趣的堆叠效果,比我之前报道的更糟糕。
这是 github 上的更新,包含完整的详细信息:
https://github.com/angular/angular.js/issues/15956#issuecomment-300324812
当我收到 AngularJS 团队的回复时,我会继续更新。
在我找到永久解决方案之前,请耐心等待。
旧建议的解决方案:
为了避免这个问题不能使用$compile
服务,或者如果你必须使用这个代码示例来解决这个问题:
$compile(child)(elmScope, function (clone) {
angular.element(child).after(clone);
angular.element(child).remove();
});
希望这对面临同样问题的其他人有价值。