abdo peroneus
abdo peroneus

Reputation: 3

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.

Upvotes: 0

Views: 891

Answers (2)

abdoutelb
abdoutelb

Reputation: 1053

From the answer by Konstantin Krass:

This ng-bind is a directive and will place a watcher on the passed variable. So the ng-bind will only apply, when the passed value does actually change.

The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary. 1

UPDATE:

the main reason is solved in the answer by georgeawg


1https://stackoverflow.com/a/23382400/1575353

Upvotes: 0

georgeawg
georgeawg

Reputation: 48968

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,

Upvotes: 2

Related Questions