【问题标题】:space is shown when selecting the dropsdown option - angularjs选择下拉选项时显示空间 - angularjs
【发布时间】:2015-05-03 17:19:25
【问题描述】:

我在 AngularJS 中创建了一个应用程序,其中包含一个使用过滤器的带有空格的下拉选项。应用程序正常工作,使用缩进空间在值之前下降,但问题是选择具有空间的选项时,在视图中也显示了空间,如下所示

实际上我想要下拉选项中的缩进空间,但唯一的问题是我不希望在上面显示的选择时显示该空间

谁能告诉我一些解决方案,以防止选择时显示空间

我的代码如下所示

JSFiddle

<select>
    <option ng-repeat="(key, value) in headers">{{value | space}}
    </option>
</select>

【问题讨论】:

    标签: javascript angularjs html-select space dropdownbox


    【解决方案1】:
    <select ng-model="selectedValue" ng-change="selVal = selectedValue.trim(); selectedValue=selVal">
        <option ng-if="selVal">{{selVal}}</option>
        <option ng-repeat="(key, value) in headers" ng-if="selVal != value.value">
            {{value | space}}
        </option>
    </select>
    

    【讨论】:

    • 这段代码发生了什么,它正在改变下拉列表......有点工作但不正确......jsfiddle.net/0yyq1Lkn
    • 它没有被洗牌,选择的元素从选项中被逐出,如果你不想要它,留下ng-if="selVal != value.value"就完成了。
    • 上述问题只发生在 chrome 和 firefox 上
    • 这是副作用,您无法在选择选项的同时获得正确的可视化。这是此代码的另一个变体:&lt;select ng-model="selectedValue" ng-change="selVal = selectedValue.trim();selectedValue=selVal"&gt; &lt;option ng-repeat="(key, value) in headers" &gt;{{ selVal == value.value ? selVal : (value | space)}}&lt;/option&gt; &lt;/select&gt;选中选项时,缩进丢失 span>
    • 你有点接近我想要的答案......但上述问题困扰着我
    【解决方案2】:

    This 在没有 jquery 的情况下尽可能接近,在选择时临时更改选项的视图状态。如果这不满足您并且您仍然希望它在下拉菜单打开时显示为缩进,请查看this question,了解如何检测选择组件的状态并相应地更新显示功能。或者,您可以create your own select directive 并管理其中的详细信息,但如果您不在很多地方使用它,我怀疑这是否值得。

    var app = angular.module('myApp', []);
    
    app.controller('ArrayController', function ($scope) {
        $scope.headers = [{
            value: 'value 1'
        }, {
            value: 'value 2',
            mainId: 12
        }, {
            value: 'value 3'
        }, {
            value: 'value 4',
            mainId: 14
        }, {
            value: 'value 5'
        }, {
            value: 'value 6',
            mainId: 18
        }];
    
        $scope.chosen = $scope.headers[0].value;
    
        $scope.display = function(header) {
            var chosenObject = _.find($scope.headers, {value: $scope.chosen});
            if (!_.isUndefined(header.mainId) && header !== chosenObject) {
                return '\u00A0\u00A0' + header.value;
            } else {
                return header.value;
            }
        }
    });
    

    此处为 HTML:

    <div ng-app='myApp' ng-controller="ArrayController">
        <br></br>
        SELECT:
        <select ng-model="chosen" ng-options="header.value as display(header) for header in headers">
        </select>
    </div>
    

    CSS 和 ng-class 还有另一种选择,fiddle here

    var app = angular.module('myApp', []);
    app.controller('ArrayController', function ($scope) {
        $scope.headers = [{
            value: 'value 1'
        }, {
            value: 'value 2',
            mainId: 12
        }, {
            value: 'value 3'
        }, {
            value: 'value 4',
            mainId: 14
        }, {
            value: 'value 5'
        }, {
            value: 'value 6',
            mainId: 18
        }];
    
        $scope.chosen = $scope.headers[0].value;
    
        $scope.isIndented = function(header) {
            var chosenObject = _.find($scope.headers, {value: header});
            return !_.isUndefined(chosenObject.mainId);
        };
    });
    
    app.filter('space', function() {
      return function(text) {
           if(_.isUndefined(text.mainId))
           {
               console.log('entered mainId');
               return text.value;
           }
           else
           {
               console.log('entered');
               return '\u00A0\u00A0' + text.value;
           }
      };
    });
    

    HTML:

    <div ng-app='myApp' ng-controller="ArrayController">
        <br></br>
        SELECT:
        <select ng-model="chosen" ng-options="header.value as (header | space) for header in headers" ng-class="{'indented-value': isIndented(chosen)}">
        </select>
    </div>
    

    CSS:

    .indented-value {
        text-indent: -9px;
    }
    

    【讨论】:

    • 我猜使用过滤器是一种干净的方式.....也在你给出的 jsifddle 中,在选择选项时未显示空间,但问题在于选项选择空间正在删除
    • 在我的方法中使用过滤器不起作用,因为我需要访问所选元素。否则,您可以使用 (header | space) 而不是 display(header),它将显示通过过滤器的文本。我已经在答案中提到它也会暂时删除选择列表中所选元素的缩进,如果这对您不起作用,您应该考虑我列出的更复杂的替代方案之一。尽管如此,您将无法同时在封闭形式中显示没有缩进的文本,在开放形式中同时显示具有缩进的文本。
    • 我们可以使用 ng-class 和 ng-selected 做任何事情吗,意思是在选择时我们可以使用 css 删除缩进
    • 它在 Chrome 41 中运行,这就是我写它的地方。在 Firefox 32 中,它使用 -4px 作为缩进。不确定IE。我向您展示了如何处理角度部分,我相信您可以处理 CSS 细节。
    • 我在删除我的答案之前走了这条路。 select 和 CSS 不能很好的跨浏览器配合,没有办法判断 select 是否打开来决定是否修剪显示的模型。我认为这个问题没有涉及使用 select 的解决方案。我认为您将不得不实现自己的下拉菜单来模仿 select 的行为。
    【解决方案3】:

    首先,这是一个很好的问题。不幸的是,我花了太多时间试图提出解决方案。我已经尝试了从 CSS 到使用 ngModelController $formatters,再到我在下面发布的解决方案(您将看到这不是最佳的)的所有方法。请注意,我认为我的解决方案不应该被选为答案。它只是“有点”有效,但与其他解决方案一样,它有一个致命的缺陷。

    但是,既然您的问题是:

    谁能告诉我一些解决方案,以防止空间 选择时显示

    我的官方回答是:

    没有跨浏览器的方法可以让它工作。再多的 CSS、jQuery 或 Angular 魔法都无法完成这项工作。虽然可能令人失望,但我认为这将是您问题的唯一正确答案。

    没有人能够为您提供一种解决方案,以防止空间显示在选择框中,同时将其保持在跨浏览器可靠运行的选项中。 Chrome 和 Firefox 允许对 select、options 和 optgroup 系列中的元素进行一定数量的样式设置,但没有什么是一致的并且适用于任何地方。

    我最好的表现是in this Plunk

    它利用 optgroup 为你做缩进的事实,但它在不同的浏览器处理它的方式上有很大的不同。使用一些你可以解决问题,但其他人不起作用(永远不会)。我发布它,所以也许有人会受到启发并想办法证明我错了。

    <body ng-app="app">
      <div ng-app='myApp' ng-controller="ArrayController">
        <div>{{selectedValue}}</div>
    
        SELECT:
        <select ng-model="selectedValue" >
          <option indented="item.mainId" ng-repeat="item in headers">{{item.value}}</option>
        </select>
      </div>
    </body>
    
    (function() {
    
      var app = angular.module('app', []);
      app.controller('ArrayController', function($scope, $timeout) {
        $scope.headers = [{
          value: 'value 1'
        }, {
          value: 'value 2',
          mainId: 12
        }, {
          value: 'value 3'
        }, {
          value: 'value 4',
          mainId: 14
        }, {
          value: 'value 5'
        }, {
          value: 'value 6',
          mainId: 18
        }];
      });
    
      app.directive('indented', function($parse) {
        return {
          link:function(scope, element, attr){
            if($parse(attr.indented)(scope)) {
              var opt = angular.element('<optgroup></optgroup>');
              element.after(opt).detach();
              opt.append(element);
            }
          }
        };
      });
    })();
    

    如果您打开问题并允许执行模仿 select 行为但使用 li 元素构建的指令,那么这将是微不足道的。但是您根本无法使用 select 来做到这一点。

    【讨论】:

    • 感谢@JoeEnzminger 提供如此详细的回答
    • 我得到了 Beppoz JSFiddle 的答复,它是一种 hack,但适用于所有浏览器,你对这些东西有什么看法和想说的
    • 我会给他赏金!这与您将获得的一样接近。
    • 它唯一不做的就是在您打开选择时显示当前选定的项目 - 所以我仍然认为我的答案是正确的:)。但它干净而聪明。
    【解决方案4】:

    根据您的代码,您可以添加一个辅助指令,以删除link 函数中的空格,一旦您选择了您的选项。

    例如,将id 添加到您的选择和指令中

    <select id="mySelect" option-without-space>
        <option ng-repeat="(key, value) in headers">{{value | space}}
        </option>
    </select>
    

    指令可能看起来像,

    app.directive('optionWithoutSpace', () => {
            return {
                restrict: 'A',
                link: function(scope, elem, attributes) {
    
                    var selectedOptionWithoutSpace = function () {
                        var selectedOption = $('#mySelect option:selected');
    
                        var optionText = selectedOption.text();
    
                        selectedOption.text(optionText.trim())
    
                        return false;
                    };
    
                    $(elem).on('change', selectedOptionWithoutSpace);
    
                }
            }
        })
    

    这有一点 jQuery 的帮助,但我认为这不是一个大问题。

    这是fiddle

    【讨论】:

    • 你能给我一个jsfiddle吗
    • 当您选择具有空间的选项时,请查看代码中的内容,一旦选择,它将永久删除空间,如果您看到完全删除空间的下拉列表,再次选择后
    • 从下拉列表中永久删除空格
    • 我得到了 Beppoz JSFiddle 的答复,它是一种 hack,但适用于所有浏览器,你对这些东西有什么看法和想说的
    • 看起来不错。作为替代方案,我已经更新了我的小提琴,所以它的行为就像你现在想要的那样。仍然不会突出显示选定的选项,但您可以通过简单的 CSS 来实现(只需选择选定的选项并更改背景颜色)。我现在正在工作,所以无法添加该技巧,可能稍后会更新。
    【解决方案5】:

    试试这个...

    更改选择框html跟随

    <select ng-model="selectedOption" ng-options="item.value for item in headers"></select>
    
    
    var app = angular.module('myApp', []);
    app.controller('ArrayController', function ($scope) {
        $scope.headers = [{
            value: 'value 1'
        }, {
            value:'value 2',
            mainId: 12
        }, {
            value: 'value 3'
        }, {
            value: 'value 4',
            mainId: 14
        }, {
            value: 'value 5'
        }, {
            value: 'value 6',
            mainId: 18
        }];
        $scope.selectedOption = $scope.headers[0]; //Add this line
    });
    
    app.filter('space', function() {
      return function(text) {
           if(_.isUndefined(text.mainId))
           {
               console.log('entered mainId');
               return text.value;
           }
           else
           {
               console.log('entered');
               return '\u00A0\u00A0' + text.value;
           }
      };
    });
    

    【讨论】:

    • 你已经删除了下拉列表中的空间,实际上我想要下拉列表中的空间,唯一的问题是我不希望在选择时显示该空间
    • 他想在查看时保留空间
    • @alsafoo 是的,你是对的,我想要下拉列表中的那个空间,唯一的问题是我不想在选择时显示那个空间
    • 使用 jquery 修剪它
    • @alsafoo 除了使用 jquery 之外别无他法......通过 jquery 我们怎么能做到这一点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多