【问题标题】:AngularJS Select preselect not workingAngularJS选择预选不起作用
【发布时间】:2014-03-08 01:23:12
【问题描述】:

即使对象相等,选择字段中的预选也不起作用:

<select ng-show="isEditMode(todo.id)" id="assignee" name="assignee" 
        ng-model="todo.assignee" required 
        ng-options="user.name for user in users">
</select>

tod​​o.assignee 包含一个用户对象,它应该与用户中的一个匹配。

Angular 似乎无法识别来自 todo.assignee 的 User 对象包含在 users 中。我可以手动执行此映射吗?

选择显示为未选择任何值。我可以(从用户中)选择一个用户并毫无问题地保存记录。

控制器

$scope.todos = Todo.query();
$scope.users = User.query();

更新

根据 cmets 的要求。给定对象的结构: $scope.todos

 [
{
    "id": 157,
    "description": "my description 0",
    "deadline": 1392073200000,
    "assignee": {
        "id": 34,
        "name": "User 1",
        "email": "user1@hotmail.com"
    },
    "comment": "my comment 0",
    "done": true
}
...
]

$scope.users

[
{
    "id": 34,
    "name": "User 1",
    "email": "user1@hotmail.com"
},
{
    "id": 35,
    "name": "User 2",
    "email": "xxc@gmail.com"
},
{
    "id": 36,
    "name": "User 3",
    "email": "xx@hotmail.com"
}
]

select的范围来自于一个repeat:

<tr ng-repeat="todo in todos | filter:query | filter:{assignee:queryAssignee} | filter:queryDone" ng-class="{danger: isDue(todo)}">
                    <td>

【问题讨论】:

  • 能否添加userstodos的结构?如果todo.assignee 包含用户对象,您可以使用类似:ng-model="todo.assignee.user.name"
  • 你必须在你的 ng-model 和 ng-show 上做 todo,但在你的范围上做 todos。
  • 我已按要求添加了结构。还提供了为什么 todo 在我的范围内的更多信息。

标签: javascript angularjs


【解决方案1】:

根据你的描述:

tod​​o.assignee 包含一个用户对象

但是您的选项值是user.name 字符串,一个对象和一个字符串永远不会匹配。

所以,替换

ng-model="todo.assignee"

ng-model="todo.assignee.name"

更新:

使用ng-options="user.name as user.name for user in users"

完整答案:

<select ng-show="isEditMode(todo.id)" 
    ng-model="todo.assignee.name" required 
    ng-options="user.name as user.name for user in users">
</select>

Plnkr: http://plnkr.co/edit/A1XdMYmACNCr3OwBuFhk?p=preview

选择作为数组中值的标签

label:这个表达式的结果将是元素的标签。该表达式很可能会引用值变量(例如 value.propertyName)。

你可以参考这里: http://docs.angularjs.org/api/ng.directive:select

更新2:

要修复副作用,您可以使用带有分隔值和显示名称的选项

<select ng-model="todo.assignee" required>
    <option ng-repeat="user in users" value="{{user}}" ng-selected="todo.assignee.name === user.name">
        {{user.name}}
    </option>
</select>

Plnkr: http://plnkr.co/edit/6tzP9ZexnYUUfwAgti9b?p=preview

说明:

之前:

当您选择其中一个选项时,它会将选项值分配给模型 todo.assignee.name,因此只需更改名称即可。

todo.assignee.name = "User 3" // like this

todo.assignee // didn't change the id & email
/* {"id": 34,
    "name": "User 1",
    "email": "user1@hotmail.com"} */

但是,现在:

When you select one of option, it assign object value to model todo.assignee, so let what you want.

todo.assignee.name = { 
    "id": 36,
    "name": "User 3",
    "email": "user3@hotmail.com"
} // like this

todo.assignee // now change the whole value
/* {"id": 36,
    "name": "User 3",
    "email": "user3@hotmail.com"} */

【讨论】:

  • 这并不能解决问题。我尝试过这个。我还在选择后添加了 {{ todo.assignee.name }}。它正确显示了名称。
  • 非常感谢您的帮助。预选现在有效。虽然它有一个副作用。它将创建无效对象。我预计 todo.assignee 中的完整用户对象将被更改,但只有名称会像这样更改。所以我需要在后台解决这个问题(根据名称设置正确的对象),这有点难看。
  • 再次更新我的答案~
  • 恐怕这会导致另一个问题。值现在是一个字符串,而不是一个对象了。所以我更喜欢后处理选择的解决方法。我认为我的情况不应该那么少,所以我很惊讶 Angular 无法处理这个问题。
  • 我添加了一些解释。不要害怕。这并不可怕,它是常见的解决方案。你可以参考这个:stackoverflow.com/questions/18647098/…
【解决方案2】:

也许它对其他人有用:

<select ng-show="isEditMode(todo.id)" id="assignee" name="assignee" 
        ng-model="todo.assignee" required 
        ng-options="user as user.name for user in users track by user.id">
</select>

魔术就在“track by user.id”中

https://docs.angularjs.org/api/ng/directive/ngOptions

【讨论】:

  • 这对我有用!需要注意的是,模型必须是对对象的引用,而不是对 todo.assignee.id 的引用。
猜你喜欢
  • 2020-05-01
  • 1970-01-01
  • 2015-10-28
  • 2015-06-05
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
相关资源
最近更新 更多