Search code examples
javascripthtmlangularjsng-bind

data-ng-bind does not work with <option> element


I've just started learning angular and got stuck on this problem. I read on AngularJS : Why ng-bind is better than {{}} in angular? that {{}} and ng-bind will give you the same outcome. However, it is not the case for the codes below:

JS

(function () {
    angular
        .module("myApp", [])
        .controller("selectCtrl2", function ($scope, $http) {
            $http({
                method: "GET",
                url: "http://localhost/testService/name.php"
            })
            .then(function (response) {$scope.names = response.data.content;},
             function (response) {$scope.names = response.statusText;});
        });
})();

HTML

<body data-ng-app="myApp">
    <div data-ng-controller="selectCtrl2">
        <select>
            <option data-ng-repeat="x in names">
                <span data-ng-bind="x"></span>
            </option>
        </select>
    </div>
</body>

ng-repeat actually created 3 option tags, but their innerHTML were spaces only. For some weird reasons, if I used {{x}}, their innerHTML would be filled with the text in an array I prepared [a, b, c]. I wonder what could be the reason.


Solution

  • It is illegal HTML to have a <span> element inside <option> elements.The only permitted content is text.

    Move the ng-bind directive to the <option> element and it will work.

    The Demo

    <script src="//unpkg.com/angular/angular.js"></script>
      <body ng-app>
        <div ng-init="names=['fred','sam','jane']">
         
            <select>
                <!-- ILLEGAL HTML
                <option data-ng-repeat="x in names">
                    <span data-ng-bind="x"></span>
                </option>
                -->
    
                <!-- PERMITTED -->
                <option data-ng-repeat="x in names" ng-bind="x">
                </option>
            </select>
        </div>
      </body>

    With the ng-bind directive as part of the <option> element, the directive will insert only the text result of the Angular Expression which is legal HTML and permitted content.

    From the MDN Docs:

    The HTML <option> element is used to define an item contained in a <select>, an <optgroup>, or a <datalist> element. As such, can represent menu items in popups and other lists of items in an HTML document.

    Content categories   None.
    Permitted content    Text, possibly with escaped characters (like `&eacute;`).
    

    — MDN HTML Element Reference - <option>

    Also see,