选择下拉选项时显示 space - angularjs

space is shown when selecting the dropsdown option - angularjs

我在 AngularJS 中创建了一个应用程序,其中包含一个下拉菜单 space 使用过滤器的选项。该应用程序可以正常使用下拉列表中的选项,在值之前缩进 space 但问题是当 select 一个选项有 space,space也显示在视图中,如下所示

实际上我想要 drop-down 选项中的缩进 space 但唯一的问题是我不希望 space 在 selection 时显示如上所示

任何人都可以告诉我一些解决方案来防止 space 在 selection

时显示

我的代码如下

JSFiddle

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

试试这个...

更改 select 框 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;
       }
  };
});

This is as close as it gets without jquery, temporarily changing the view state of the option when it's chosen. If that doesn't satisfy you and you still want it to be shown indented when the dropdown menu is open, check out this question on how to detect the state of the select component and update the display function accordingly. Alternatively, you can 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;
}

根据您的代码,您可以添加一个辅助指令,以便在您的选项得到 selected 后删除 link 函数中的 space。

例如,将 id 添加到您的 select 和指令

<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

首先,这是一个很好的问题。不幸的是,我花了太多时间试图提出解决方案。我已经尝试了从 CSS 到使用 ngModelController $formatters 的所有方法,再到我在下面发布的解决方案(如您所见,这不是最优的)。请注意,我认为我的解决方案不值得 selected 作为答案。它只是 "sorta" 有效,但与其他解决方案一样,它有一个致命的缺陷。

但是,由于您的问题是:

can anyone please tell me some solution to prevent the space to display when selection

我的官方回答是:

没有跨浏览器的方式来实现这一点。再多的 CSS、jQuery 或 Angular 魔法也无法使这项工作成功。虽然这可能令人失望,但我认为这将是您问题的唯一正确答案。

没有人能够为您提供一种解决方案来阻止 space 显示在 select 框中,同时将其保留在跨浏览器可靠工作的选项中。 Chrome 和 Firefox 允许对 select、选项和 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.

<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>