无法设置ng-options的选定值

Ini*_*igo 15 angularjs angularjs-ng-options

我正在尝试填充下拉选择选项列表,并使用ng-model和ng-options设置默认选定值.

我在视图中有以下代码:

<select ng-model="thisTour.site" ng-options="site.name for site in siteList"></select>
Run Code Online (Sandbox Code Playgroud)

在我的控制器中:

    $scope.siteList = [
        { id: 1, name: 'cycling'},
        { id: 2, name: 'walking'},
        { id: 3, name: 'holidays'}
    ]

    $scope.thisTour.site = { id: 2, name: 'walking'};
Run Code Online (Sandbox Code Playgroud)

该列表正在填充来自siteList对象的正确3个选项,但是默认情况下并不是按照我的预期选择行走?为什么不?

现在,当我改变这个:

$scope.thisTour.site = { id: 2, name: 'walking'};
Run Code Online (Sandbox Code Playgroud)

对此:

$scope.thisTour.site = $scope.siteList[1];
Run Code Online (Sandbox Code Playgroud)

现在它有效.为什么?这不是一回事吗?

PSL*_*PSL 46

这是因为angular查找对象相等以将其与您的语法绑定并且在您的情况下$scope.siteList[1]不等于{ id: 2, name: 'walking'};(2个对象只有在它们指向相同的引用时才相等).您可以通过多种方式解决这个问题,一种简单的方法是使用track by带有ng-options的语法来指定track by id,这将使绑定对象的指定属性而不是对象引用本身跟踪ng-option的选项.

<select ng-model="thisTour.site" 
    ng-options="site.name for site in siteList track by site.id"></select>
Run Code Online (Sandbox Code Playgroud)

您还可以使用语法来最小化设置ng-model以仅使用select作为语法中的部分来指定id : -

例:-

ng-options="site.id as site.name for site in siteList"
Run Code Online (Sandbox Code Playgroud)

和模型只是: -

 $scope.thisTour.site = 2;
Run Code Online (Sandbox Code Playgroud)

angular.module('app', []).controller('ctrl', function($scope){
  $scope.thisTour = {};
 $scope.siteList = [
        { id: 1, name: 'cycling'},
        { id: 2, name: 'walking'},
        { id: 3, name: 'holidays'}
    ]

    $scope.thisTour.site = { id: 2, name: 'walking'};
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <select ng-model="thisTour.site" ng-options="site.name for site in siteList track by site.id"></select>
  {{thisTour.site}}
  </div>
Run Code Online (Sandbox Code Playgroud)

文档

trackexpr: - 在处理对象数组时使用.此表达式的结果将用于标识数组中的对象.trackexpr很可能会引用值变量(例如value.propertyName).通过这种方式,即使重新创建选项(例如,从服务器重新加载),也会保留选择.

另外值得注意的是:

不要在同一表达式中使用select as和track by.它们不是为了协同工作而设计的.

  • +1表示`不要在同一个表达式中使用select as和track by.它们不是为了合作而设计的 (2认同)