1

我需要的是能够通过文本对选择元素的子选项节点进行排序,同时保持它们的值关联。我可以让他们按字母顺序排列并与他们的键解除关联,或者我可以在不按字母顺序排列的情况下关联他们的键。

我知道有一种直接访问 JSON 的方法,但这是一个分阶段的实现,该功能将在稍后推出。现在,我必须通过前置脚本块加载 json,直到MyInterface.js加载应用程序脚本。

我研究了自定义过滤器,但这就是与键分离的来源。如果 JSON 需要采用完全不同的格式,我愿意采用它。

这就是我所拥有的...

HTML

<!doctype html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
  </head>
  <body>
    <div ng-app="MyInterface" ng-controller="SimpleJSON">
      <select name="index_category"
        ng-model="IndexCategory"
        ng-init="IndexCategory = IndexCategory || '0'"
        ng-options="option in JSON.Categories | orderObjectBy:'val'">
        <option value="0">Select Animal...</option>
      </select>
    </div>
    <script>
      var json = {
        "123":"Zebra",
        "456":"Monkey",
        "789":"Anteater"
      };
    </script>
    <script src="MyInterface.js"></script>
  </body>
</html>

我的界面.js

(function(json) {

  // AngularJS Module
  var MyInterface = angular.module('MyInterface', []);

  // Custom Filters
  MyInterface.filter('orderObjectBy', function() {
    return function(items, field, reverse) {
      var filtered = [];
      angular.forEach(items, function(item) {
        filtered.push(item);
      });
      filtered.sort(function(a, b) {
        return a[field] > b[field] ? 1 : -1;
      });
      if(reverse) filtered.reverse();
      return filtered;
    };
  });

  // Controllers
  MyInterface.controller('SimpleJSON', function($scope) {
    $scope.JSON = angular.fromJson(json);
  });

})(json);

本质上,选择需要具有的选项是:

<option value="0">Select Animal...</option>
<option value="789">Anteater</option>
<option value="456">Monkey</option>
<option value="123">Zebra</option>

包含已接受答案的更改

HTML

<!doctype html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
  </head>
  <body>
    <div ng-app="MyInterface" ng-controller="SimpleJSON">
      <select name="index_category"
        ng-model="IndexCategory"
        ng-options="option.value for option in JSON track by option.key">
        <option value="">Select Animal...</option>
      </select>
    </div>
    <script>
      var json = [
        { key:"123", value:"Zebra" },
        { key:"456", value:"Monkey" },
        { key:"789", value:"Anteater" }
      ];
    </script>
    <script src="MyInterface.js"></script>
  </body>
</html>

我的界面.js

(function(json) {

  // AngularJS Module
  var MyInterface = angular.module('MyInterface', []);

  // Controllers
  MyInterface.controller('SimpleJSON', function($scope, orderByFilter) {

    // Load JSON
    $scope.JSON = angular.fromJson(json);

    // Alphabetize by Value
    $scope.JSON = orderByFilter($scope.JSON, 'value');

  });

})(json);
4

2 回答 2

2

您需要使用带有 ng-options 的对象数组。即,示例

 $scope.animals= [
    {key:"123", value:"Zebra"},
    {key:"456",value: "Monkey"},
    {key:"789", value: "Anteater"}
  ];

并且由于您只想键入,因此ng-model您需要使用 syntax ng-options="option.key as option.value for option in animals | orderBy:'value'"。对于默认选项,只需提供一个选项value=""

<select name="index_category" ng-model="IndexCategory" ng-options="option.key as option.value for option in animals| orderBy:'value'">
    <option value="">Select Animal...</option>
</select>

演示

angular.module('app', []).controller('ctrl', function($scope) {
  $scope.JSON = [{
    key: "123",
    value: "Zebra"
  }, {
    key: "456",
    value: "Monkey"
  }, {
    key: "789",
    value: "Anteater"
  }];

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <select name="index_category" ng-model="IndexCategory" ng-options="option.key as option.value for option in JSON | orderBy:'value'">
    <option value="">Select Animal...</option>
  </select>
  {{IndexCategory}}
</div>

您还需要记住 DOM 过滤器很昂贵,因为它们在摘要周期中至少运行两次。如果您的选择列表是动态的,请不要放置 DOM 过滤器,而是可以在绑定数据之前在控制器中对其进行排序。在您的情况下,您可以在控制器中使用简单的本机排序或 orderBy 过滤器本身。

IE

angular.module('app', []).controller('ctrl', function($scope, orderByFilter) {
  $scope.animals= [{
    key: "123",
    value: "Zebra"
  }, {
    key: "456",
    value: "Monkey"
  }, {
    key: "789",
    value: "Anteater"
  }];
  /*Using orderByFilter*/
  $scope.animals= orderByFilter($scope.JSON, 'value');
  /*Or just use native sort*/
  //$scope.animals.sort(function(a, b){ return a['value'] > b['value'] });

});

你的看法就是:

 ng-options="option.key as option.value for option in animals">

如果您没有从服务器获取数组格式数据的选项并且需要进行转换,只需在控制器中执行,如下所示:

$scope.animals = convertToOptions(optionsObject);

function convertToOptions(obj){
    var options = [];
    angular.forEach(obj, function(value, key){
        options.push({key:key, value:value});
    });
    return options;
  }

如果您真的担心将选项值设置为与key您需要使用的属性相同的值track by。IE

  ng-options="option.value for option in animals track by option.key">

旁注:不要将 ng-init 与 ng-options 一起使用。

从文档:

ngInit 唯一合适的用途是为 ngRepeat 的特殊属性设置别名,如下面的演示所示。除了这种情况,您应该使用控制器而不是 ngInit 来初始化作用域上的值。

于 2015-01-07T20:35:10.357 回答
0

Angular 1.x 中的 ngOptions 当前不支持排序对象属性。

https://github.com/angular/angular.js/issues/1286

但是,您可以应用toArray下面链接的自定义过滤器将对象转换为数组,然后orderBy在转换过滤器之后链接过滤toArray器:

http://ngmodules.org/modules/angular-toArrayFilter

item in items | toArray | orderBy: 'date'
于 2015-09-09T13:50:40.753 回答