How to apply font-family in ng-option for each opt

2019-07-14 02:40发布

I want to show a combobox whose all option font will be different.

When using the ng-options directive in AngluarJS to fill in the options for a <select> tag I cannot figure out how to set the font-family for each option.

$scope.reportFontload=["Andale Mono","Arial","Arial Black","Bitstream Charter","Century Schoolbook L","Comic Sans MS","Courier 10 Pitch","Courier New","DejaVu Sans"];

<select ng-options="font for font in reportFontload" ng-model="selected">
 <option value="" disabled selected>Font Family</option>        
 </select>

For ng-repeat if i use to apply style="font-family:{{font}}". It works for each and every option in the ng-repeat.

Here is the example: fiddle

<select ng-model="selected">
  <option value="" disabled selected>Fonts</option> 
  <option ng-repeat="font in reportFontload" value={{font}} style="font-family:{{font}}">{{font}}</option>
</select>

I need to know , Why font-family is not works in ng-option. Guide me any possible answer.

2条回答
ら.Afraid
2楼-- · 2019-07-14 03:30

You can not create a select(combo box) whose options will have different font. As per my knowledge this is not allowed in HTML and CSS.

But you can achive this if you use different commbo like: Bootstrap or some other this.

Here is a bootstrap example with plain HTML.

<div class="dropdown">
  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
    Dropdown
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
    <li style="font-family:Arial"><a href="#">Action</a></li>
    <li style="font-family:Arial Blackl"><a href="#">Another action</a></li>
    <li style="font-family:Andale Mono"><a href="#">Something else here</a></li>
    <li style="font-family:Courier New"><a href="#">Separated link</a></li>
  </ul>
</div>

Plunker Here

Now for usage in angular you may use https://angular-ui.github.io/bootstrap/ Or you can write your own implementation for it.

查看更多
Ridiculous、
3楼-- · 2019-07-14 03:31

I have created an optionsAttribute directive that can transform the attributes of your option tags after they are rendered by ngOptions.

DEMO

Directive

.directive('optionsAttribute', function($parse, $timeout) {
  return {
    restrict: 'A',
    compile: function(tElem, tAttr) {
      var transform = $parse(tAttr.optionsAttributeTransform);
      return function(scope, elem, attr) {
        scope.$watch(attr.optionsAttribute, function(data) {

          var options = elem.children();
          options = Array.prototype.slice.call(options, options.length - data.length);

          angular.forEach(options, function(option, index) {
            var optionElement = angular.element(option);
            var newAttribute;
            var label;

            if(angular.isDefined(attr.optionsAttributeTransform)) {
              newAttribute = transform(scope, { 
                $data: data[index],
                $label: option.innerHTML,
                $index: index
              });

              angular.forEach(newAttribute, function(value, attribute) {
                optionElement.attr(attribute, value);
              });
            }

          });

        });
      };
    }
  };
});

Usage

  1. Provide the array value you have provided in the ngOptions directive in the optionsAttribute directive.

e.g.

<select ng-options="font for font in reportFontload"
        options-attribute="reportFontload">
</select>
  1. Add a callback in the optionsAttributeTransform directive that returns an json object that represents the attributes to be appended in each of the options tag. The callback itself is provided with 2 values:

$data - represents each of the item in the array provided in #1.

$index - represents the index of the $data.

e.g.

HTML

<select ng-options="font for font in reportFontload"
        ng-model="selected"
        options-attribute="reportFontload"
        options-attribute-transform="{ 'style': 'font-family: ' + $data }">
</select>

or an alternative is to provide a function callback

JAVASCRIPT

$scope.transform = function(fontFamily) {
  return { 'style': 'font-family ' + fontFamily };
};

HTML

<select ng-options="font for font in reportFontload"
        ng-model="selected"
        options-attribute="reportFontload"
        options-attribute-transform="transform($data)">
</select>

LIMITATIONS

The directive is only limited towards array, objects excluded, although there is a way to tweak the current directive to also work with objects, but the current implementation is already sufficient for the OP's problem.

UPDATE

I tweaked the directive above to also work with object collections, the usage still says the same:

DEMO

(function(ng) {

    'use strict';

    var app = ng.module('options.attribute', []);

    app.directive('optionsAttribute', function($parse) {
        return {
            restrict: 'A',
            compile: function(tElem, tAttr) {

                var transform = $parse(tAttr.optionsAttributeTransform);

                return function(scope, elem, attr) {

                    scope.$watch(attr.optionsAttribute, function(collection) {

                        var options = elem.children();

                        collection = new Collection(collection);

                        options = Array.prototype.slice.call(options, options.length - collection.getLength());

                        ng.forEach(options, function(option, index) {

                            var newAttributes = transform(scope, {
                                $data: collection.getItem(index),
                                $label: option.innerHTML,
                                $index: collection.getIndex(index)
                            });

                            var optionElement = angular.element(option);

                            ng.forEach(newAttributes, function(value, attribute) {

                                optionElement.attr(attribute, value);

                            });

                        });

                    }, true);

                };

            }
        };
    });

    function Collection(collection) {

        var self = this;
        var indexes;

        if(angular.isObject(collection)) {

            if(Object.keys) {
                indexes = Object.keys(collection);
            } else {
                ng.forEach(collection, function(item, index) {
                    indexes.push(index);
                });
            }

            self.getItem = function(index) {
                return collection[indexes[index]];
            };

            self.getLength = function() {
                return indexes.length;
            };

            self.getIndex = function(index) {
                return indexes[index];
            };

        } else if(angular.isArray(collection)) {

            self.getItem = function(index) {
                return collection[index];
            };

            self.getLength = function() {
                return collection.length;
            };

            self.getIndex = function(index) {
                return index;
            };

        }

    }


})(angular);
查看更多
登录 后发表回答