【问题标题】:Object.keys() not working in ng-optionsObject.keys() 在 ng-options 中不起作用
【发布时间】:2016-08-19 16:27:06
【问题描述】:

我正在尝试使用 ng-options 创建一个下拉列表:

<!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 中的结果数组来从对象的键中获取下拉值。

我正在尝试创建 案例 1 的效果。我在 case 2 的尝试没有奏效,但是在 case 3 中实现的类似事情正在奏效。

谁能说出案例2不起作用的原因?

【问题讨论】:

    标签: javascript angularjs drop-down-menu html-select ng-options


    【解决方案1】:

    更新
    正如 Zen 的回答所指出的,Object.keys()ng-repeat 中不起作用的原因是它被评估的上下文(即$scope 的上下文)。

    Angular 以(key, val) 的形式内置了这个功能。有时,Angular express 中对原生 javascript 函数的支持是有限的,在这种情况下,Angular 可能无法将 Object.keys() 理解为 ng-options 的来源。将案例 2 中的 &lt;select&gt; 更改为:

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

    编辑:(适用于回答)如果您希望选择选项的值不成为对象的值(例如101,@ 987654332@等),你可以写&lt;select ng-model="sortKey2" ng-options="key as key for (key,val) in books[0]"&gt;

    【讨论】:

    • 你会发现Angular对表达式中的javascript函数的支持有时是有限的。这似乎是其中之一。
    • 您可以将此添加到答案中吗?另外,我在您的回答中添加了一些内容;只需验证它是否正确,因为我不是 Angular 专家。
    • 嘎...不敢相信我写的是key for...而不是key as key for...。我已更新我的答案以包含此内容,因为它是正确的形式。谢谢!
    【解决方案2】:

    所有绑定表达式都相对于$scope 进行评估。因此,当您编写 for x in Object.keys(books[0]) 时,Angular 会将其运行为 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];
        });
    }])
    

    【讨论】:

    • 啊,好电话。我的假设是 Angular 不理解 Object.keys(),但是您对评估它的上下文的解释更有意义。但是,我不认为使用$rootScope 是一个好的解决方案,尤其是在key as key for (key, val) in ... 的支持下。
    猜你喜欢
    • 1970-01-01
    • 2018-08-29
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    相关资源
    最近更新 更多