2

Я пытаюсь создать выпадающий список с помощью нг-опций:Object.keys() не работает в нг-вариантах

<!DOCTYPE html> 
<html ng-app="m1"> 
    <head> 
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js'></script> 
    </head> 
    <body ng-controller="c1"> 
    <div> 
     Sort1 
     <select ng-model="sortKey1"> 
     <option value="bookId">By Id</option> 
     <option value="bookTitle">By Title</option> 
     <option value="cost">By Cost</option> 
     </select> 
    </div> 
    <div> 
     Sort2 
     <select ng-model="sortKey2" ng-options="x for x in Object.keys(books[0])"> 
     </select> 
    </div> 
    <div> 
     Sort3 
     <select ng-model="sortKey3" ng-options="x for x in bookKeys"> 
     </select> 
    </div> 
    </body> 
    <script type="text/javascript"> 
    var m1 = angular.module("m1", []); 

    m1.controller('c1',function($scope) 
    { 
     $scope.books = [ 
     { 
      "bookId": 101, 
      "bookTitle": "Angular JS", 
      "cost":375, 
     }, 
     { 
      "bookId": 102, 
      "bookTitle": "Instant AngularJS Starter", 
      "cost":150, 
     }, 
     { 
      "bookId": 103, 
      "bookTitle": "Ng-Book: The Complete Book on AngularJS", 
      "cost":4657, 
     }]; 

     console.log(Object.keys($scope.books[0])); 
     $scope.bookKeys = Object.keys($scope.books[0]); 
    }); 
    </script> 
</html> 

Я пытаюсь получить значение выпадающего из ключей объекта перечисляется путем вызова Object.keys() на объект, а затем используя результирующий массив в ng-options.

Я пытаюсь создать эффект case 1. Моя попытка случай 2 не работает, однако аналогичная вещь реализована в случай 3 работает.

Может кто-нибудь сказать причину, почему case 2 не работает?

ответ

4

Update
Как указано в ответе Дзэн, причина Object.keys() не работает в ng-repeat связано с контекстом, в котором оценивается (что, будучи в контексте $scope).

Угловая имеет встроенную функцию в виде (key, val). Иногда поддержка встроенных функций javascript в Angular Express ограничена, и в этом случае Angular, вероятно, не понимает Object.keys() как источник для ng-options. Изменение <select> в вашем случае 2 к:

<select ng-model="sortKey2" ng-options="key as key for (key,val) in books[0]"> 

Рабочий пример:

var m1 = angular.module("m1", []); 
 

 
    m1.controller('c1', function($scope) { 
 
     $scope.books = [{ 
 
     "bookId": 101, 
 
     "bookTitle": "Angular JS", 
 
     "topic": "AngularJS", 
 
     "author": "Green", 
 
     "cost": 375, 
 
     }, { 
 
     "bookId": 102, 
 
     "bookTitle": "Instant AngularJS Starter", 
 
     "topic": "AngularJS", 
 
     "author": "Dan Menard", 
 
     "cost": 150, 
 
     }, { 
 
     "bookId": 103, 
 
     "bookTitle": "Ng-Book: The Complete Book on AngularJS", 
 
     "topic": "AngularJS", 
 
     "author": "Ari Lerner", 
 
     "cost": 4657, 
 
     }]; 
 

 
     console.log(Object.keys($scope.books[0])); 
 
     $scope.bookKeys = Object.keys($scope.books[0]); 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script> 
 
<div ng-app="m1" ng-controller="c1"> 
 
    <div> 
 
    Sort1 
 
    <select ng-model="sortKey1"> 
 
     <option value="bookId">By Id</option> 
 
     <option value="bookTitle">By Title</option> 
 
     <option value="topic">By Topic</option> 
 
     <option value="author">By Author</option> 
 
     <option value="cost">By Cost</option> 
 
    </select> 
 
    </div> 
 
    <div> 
 
    Sort2 
 
    <select ng-model="sortKey2" ng-options="key as key for (key,val) in books[0]"> 
 
    </select> 
 
    </div> 
 
    <div> 
 
    Sort3 
 
    <select ng-model="sortKey3" ng-options="x for x in bookKeys"> 
 
    </select> 
 
    </div> 
 
</div>

EDIT: (применяется для ответа) Если вы хотите, чтобы значение а выберите вариант, чтобы не стать значением объекта (например, 101, AngularJS и т. д.), лет u можете написать <select ng-model="sortKey2" ng-options="key as key for (key,val) in books[0]">

+0

Отлично! Но почему 'Object.keys()' не работает? –

+1

Вы обнаружите, что угловая поддержка функций javascript внутри выражения иногда ограничена. Кажется, это один из этих случаев. – Lex

+0

Можете ли вы добавить это в ответ? Кроме того, я добавил что-то к вашему ответу; просто проверьте, правильно ли это, потому что я не специалист по угловым измерениям. –

1

Все обязательные выражения оцениваются относительно $scope. Поэтому, когда вы пишете for x in Object.keys(books[0]), угловой пробегает его как for(x in $scope.Object.keys([books[0])). По-видимому, Object не определен в цепочках видимости. Если вы хотите, чтобы он работал, вы можете скопировать все глобальные переменные в $rootScope, что, похоже, не так уж плохо.

m1.run([`$rootScope`, function($rootScope){ 
    var keys = Object.getOwnPropertyNames(window); 
    keys.forEach(key => { 
     $rootScope[key] = window[key]; 
    }); 
}]) 
+0

Ах, хороший звонок. Мое предположение заключалось в том, что Angular не понимал 'Object.keys()', но ваше объяснение контекста, в котором оно оценивается, имеет гораздо больший смысл. Тем не менее, я не думаю, что использование '$ rootScope' является хорошим решением, особенно с поддержкой ключа в качестве ключа для (key, val) в ...'. – Lex

Смежные вопросы