如何在动态更改选项时修复IE选择问题

dnc*_*253 64 internet-explorer html-select angularjs

我有一组选择,都有相同的选项.然后我通过过滤器运行这些选项,以便在选择中不显示在不同选择中选择的任何选项.看到这个jsFiddle(在非IE浏览器中)看看我的意思.基本上我阻止在选择中多次选择相同的选项

现在,我所做的事情在IE中存在问题.在IE中打开那个小提琴(我只在IE9中试过它,但我猜测以前的版本有同样的问题).将最后一个选择更改为AAA.注意3个其他选择如何改变他们显示的内容.他们的模型并没有改变,但是当选项改变时,IE会以某种方式窒息.

我的问题是第一,我是否在使用此功能时出错?这个代码完全符合我想要的Chrome和FF,但我做的是我不应该做的事情吗?其次,我怎样才能在IE中解决这个问题?我尝试了一些可以清除和重新设置模型的超时,但事情明显地跳了起来.我想知道是否有一个良好,干净,低影响的解决方法.

任何帮助将非常感激.谢谢.

--UPDATE--

这已经在Angular本身使用版本1.3.3 修复,使用下面的AS Ranjan解决方案.看看1.3.3的新小提琴:http://jsfiddle.net/m2ytyapv/

//dummy code so I can post the edit
Run Code Online (Sandbox Code Playgroud)

Mat*_*erg 29

我在另一个晚上经历了同样的问题,在抛出我能想到的一切后,我得出的结论是IE在使用选择时不想处理更新过滤器.

我的解决方案是将您的选择更改为如下所示:

 <select class="selectList" ng-repeat="currId in selectedIds" ng-model="selectedIds[$index]"  ng-options="currOption.id as currOption.value for currOption in myObj | myfilter:selectedIds:$index" data-ng-change="fixIE()"></select>
Run Code Online (Sandbox Code Playgroud)

他们现在有一个班级和一个ng-change.然后在您的控制器中执行以下有趣的代码:

$scope.fixIE = function(){
    //code to check if IE so the other browsers don't get this ugly hack.
    var selectLists = document.querySelectorAll(".selectList");
    for(var x = 0;x  < selectLists.length; x++){
        selectLists[x].parentNode.insertBefore(selectLists[x], selectLists[x]);
    }       
};
Run Code Online (Sandbox Code Playgroud)

它的作用是将元素从DOM中删除并将它们替换为相同的位置.这是一个工作小提琴jsFiddle

我试过的其他一些不涉及javascript的解决方案就像切换选择的显示/可见性之类的东西.他们的zIndex被移动了.唯一确定它的是这段代码.


kku*_*rni 20

我有修复.

我们必须添加和删除选项列表以触发IE8中的渲染.

http://kkurni.blogspot.com.au/2013/10/angularjs-ng-option-with-ie8.html


/**
 * Fix for IE select menus getting stuck when their underlying list changes.
 * Original code: http://kkurni.blogspot.com.au/2013/10/angularjs-ng-option-with-ie8.html
 * 
 * Set the `ie-select-fix` attribute to the model expression that should trigger the list to re-render.
 * 
 * @example <select ng-model="modelValue" ie-select-fix="itemList" ng-options="item.label for item in itemList">
 */
app.directive('ieSelectFix', ['$document',
        function($document) {

            return {
                restrict: 'A',
                require: 'ngModel',
                link: function(scope, element, attributes, ngModelCtrl) {
                    var isIE = $document[0] && $document[0].attachEvent;
                    if (!isIE) return;

                    var control = element[0];
                    //to fix IE8 issue with parent and detail controller, we need to depend on the parent controller
                    scope.$watch(attributes.ieSelectFix, function() {
                        // setTimeout is needed starting from angular 1.3+
                        setTimeout(function() {
                            //this will add and remove the options to trigger the rendering in IE8
                            var option = document.createElement("option");
                            control.add(option,null);
                            control.remove(control.options.length-1);
                        }, 0);
                    });
                }
            }
        }
    ]);
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这解决了我的问题没有任何问题.我建议您将这些代码添加到您的答案中,以供将来的读者阅读. (3认同)
  • 做得好!这非常有效.当在ngRepeat中使用大量项目时,我们遇到了使用$ timeout的解决方案的一些性能问题.这样解决了这个问题. (3认同)

dnc*_*253 12

我终于想出了一个适合我需求的解决方案.基本上似乎正在发生的事情是所选索引处的选项文本指向以前在该位置的旧字符串.我相信更改此文本会更新字符串和/或引用.我做了这样的事情:

angular.forEach($("select"), function (currSelect) {
     currSelect.options[currSelect.selectedIndex].text += " ";
});
Run Code Online (Sandbox Code Playgroud)

这是更新的小提琴:http://jsfiddle.net/H48sP/35/

在我的应用程序中,我有一个指令,其中这些选择是,所以我做element.find("select")而不是$("select")限制元素选择的范围.文本被强制刷新,因此在所有摘要周期运行后正确显示.

如果您遇到同样的问题,可能需要$timeout在小提琴中添加类似内容,和/或如果出现问题,您可能需要稍后删除添加到选项文本中的额外空间.


A. *_*jan 5

在angular.js中selectDirective的render函数中添加几行以下的地方(用粗体标记为**)对我来说很好.我正在寻找除了修补angularJS或下面给出的forEach之外是否还有其他可能的解决方案?

            if (existingOption.label !== option.label) {
              lastElement.text(existingOption.label = option.label);
              **lastElement.attr('label', existingOption.label);**
            }
Run Code Online (Sandbox Code Playgroud)

              (element = optionTemplate.clone())
                  .val(option.id)
                  .attr('selected', option.selected)
                  .text(option.label);
              **element.attr('label', option.label);**
Run Code Online (Sandbox Code Playgroud)

问题是如果IE中的标签为空,则HTMLOptionElement的label属性与text属性不同.

通过在加载屏幕后添加以下代码并查看FF和IE的Web控制台以查看差异,可以看到这一点.如果取消注释标签设置为文本的最后一行,它可以正常工作.或者如上所述修补angular.js.

// This is an IE fix for not updating the section of dropdowns which has ng-options with filters
angular.forEach($("select"), function (currSelect) {
    console.log("1.text ", currSelect.options[currSelect.selectedIndex].text);
    console.log("1.label ", currSelect.options[currSelect.selectedIndex].label);
    //console.log("1.innerHTML ", currSelect.options[currSelect.selectedIndex].innerHTML);
    //console.log("1.textContent ", currSelect.options[currSelect.selectedIndex].textContent);
    //console.log("1.cN.data ", currSelect.options[currSelect.selectedIndex].childNodes[0].data);
    //console.log("1.cN.nodeValue ", currSelect.options[currSelect.selectedIndex].childNodes[0].nodeValue);
    //console.log("1.cN.textContent ", currSelect.options[currSelect.selectedIndex].childNodes[0].textContent);
    //console.log("1.cN.wholeText ", currSelect.options[currSelect.selectedIndex].childNodes[0].wholeText);
    //console.log("1. ", currSelect.options[currSelect.selectedIndex], "\n");

    //currSelect.options[currSelect.selectedIndex].label = "xyz";
    //currSelect.options[currSelect.selectedIndex].label = currSelect.options[currSelect.selectedIndex].text;
});
Run Code Online (Sandbox Code Playgroud)