使用 AngularJS 和 ng-repeat 初始化选择

Posted

技术标签:

【中文标题】使用 AngularJS 和 ng-repeat 初始化选择【英文标题】:Initializing select with AngularJS and ng-repeat 【发布时间】:2013-09-09 22:10:08 【问题描述】:

我正在尝试让选择框从使用 ng-repeat 和 AngularJS 1.1.5 的预填充选项开始。相反,选择总是从没有选择任何内容开始。它还有一个空选项,我不想要。我认为没有任何选择会有副作用。

我可以使用 ng-options 而不是 ng-repeat 来完成这项工作,但我想在这种情况下使用 ng-repeat。虽然我缩小的示例没有显示它,但我也想设置每个选项的标题属性,据我所知,使用 ng-options 没有办法做到这一点。

我认为这与常见的 AngularJs 范围/原型继承问题无关。至少我在 Batarang 检查时没有看到任何明显的东西。另外,当您在 UI 中选择一个选项时,模型会正确更新。

这是 html

<body ng-app ng-controller="AppCtrl">
    <div>
        Operator is: filterCondition.operator
    </div>
    <select ng-model="filterCondition.operator">
       <option 
           ng-repeat="operator in operators" 
           value="operator.value"
       >
           operator.displayName
       </option>
    </select>
</body>

还有 javascript

function AppCtrl($scope) 

    $scope.filterCondition=
        operator: 'eq'
    

    $scope.operators = [
        value: 'eq', displayName: 'equals',
        value: 'neq', displayName: 'not equal'
     ]

JS 小提琴:http://jsfiddle.net/coverbeck/FxM3B/2/

【问题讨论】:

ngOption 之所以被创建,是因为 ngRepeat 没有干净的方法来做到这一点。 ngRepeat 在选择选项后展开。您是否尝试过在您的选项上设置 ngSelect 是的! ngSelected 起作用了!我将发布一个更新的工作 JsFiddle。 应该注意的是,在 AngualrJS 1.2 中,这段代码的工作方式有所不同——它不会创建一个新的空 【参考方案1】:

好的。如果您不想使用正确的方式ng-options,您可以为option 指令添加带有条件检查逻辑的ng-selected 属性,以使预选工作。

<select ng-model="filterCondition.operator">
    <option ng-selected="operator.value == filterCondition.operator"
            ng-repeat="operator in operators"
            value="operator.value">
      operator.displayName
    </option>
</select>

Working Demo

【讨论】:

我会给你功劳,因为你自己想出来并做了完整的例子。尽管我不同意您关于 ng-options 是“正确方法”的评论。 :) 我自己一直使用 ng-options,但这需要做一些 ng-options 不支持的事情,尽管它很小。 Angular 文档说您也可以使用 ng-repeat。谢谢,查尔斯 谢谢,这是禁用某些选项的简单方法。 ng-options 仅在其用例适合您的情况下才是正确的。您可能需要在选项/optgroup 字段等中使用额外的属性/类。 “正确的方法”有时不起作用(例如,如果您想翻译填充选项名称的字符串) 我认为 ng-selected 表达式必须没有 :ng-selected="operator.value == filterCondition.operator"【参考方案2】:

对于 select 标签,angular 提供了 ng-options 指令。它为您提供了设置选项和设置默认值的特定框架。这是使用 ng-options 按预期工作的更新小提琴:http://jsfiddle.net/FxM3B/4/

更新的 HTML(代码保持不变)

<body ng-app ng-controller="AppCtrl">
<div>Operator is: filterCondition.operator</div>
<select ng-model="filterCondition.operator" ng-options="operator.value as operator.displayName for operator in operators">
</select>
</body>

【讨论】:

嗨 Jeremy -- 我正在尝试在没有 ng-options 的情况下执行此操作。就像我在我的问题和回复 Shaun 时所说的那样,我想在每个选项上设置 title 属性,据我所知,我不能用 ng-options 做到这一点。谢谢,查尔斯【参考方案3】:

angular 向 select 注入一个空选项元素的事实是,默认绑定到它的模型对象在初始化时带有一个空值。

如果你想选择一个默认选项,那么你可以在控制器的范围内设置它

$scope.filterCondition.operator = "your value here";

如果你想要一个空的选项占位符,这对我有用

<select ng-model="filterCondition.operator" ng-options="operator.id as operator.name for operator in operators">
  <option value="">Choose Operator</option>
</select>

【讨论】:

这很好,但是 Angular 会创建一个空白选项。如何避免这种情况?【参考方案4】:

感谢 TheSharpieOne 指出 ng-selected 选项。如果那是作为答案而不是评论发布的,我会做出正确的答案。

这是一个有效的 JSFiddle:http://jsfiddle.net/coverbeck/FxM3B/5/。

我还更新了小提琴以使用我在原始帖子中遗漏的 title 属性,因为它不是问题的原因(但这是我想使用 ng-repeat 而不是 ng -选项)。

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: filterCondition.operator</div>
<select ng-model="filterCondition.operator">
   <option ng-repeat="operator in operators" title="operator.title" ng-selected="operator.value == filterCondition.operator" value="operator.value">operator.displayName</option>
</select>
</body>

JS:

function AppCtrl($scope) 

    $scope.filterCondition=
        operator: 'eq'
    

    $scope.operators = [
        value: 'eq', displayName: 'equals', title: 'The equals operator does blah, blah',
        value: 'neq', displayName: 'not equal', title: 'The not equals operator does yada yada'
     ]

【讨论】:

抱歉发表评论。我不想做一个例子,我也不是 100% 确定它会起作用。这只是一种预感。【参考方案5】:

按照建议,您需要使用 ng-options,不幸的是,我认为您需要引用数组元素作为默认值(除非该数组是字符串数组)。

http://jsfiddle.net/FxM3B/3/

JavaScript:

function AppCtrl($scope) 


    $scope.operators = [
        value: 'eq', displayName: 'equals',
        value: 'neq', displayName: 'not equal'
     ]

    $scope.filterCondition=
        operator: $scope.operators[0]
    

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: filterCondition.operator.value</div>
<select ng-model="filterCondition.operator" ng-options="operator.displayName for operator in operators">
</select>
</body>

【讨论】:

你知道为什么并且你确定吗?文档 (docs.angularjs.org/api/ng.directive:select) 说您只需要在绑定到非字符串值时使用 ng-options。就像我说的那样,我想使用 title 属性,而 ng-options 无法做到这一点。类似 我相信文档中的注释有点不清楚,实际上意味着您必须为模型使用字符串并为选项设置字符串数组。如果您不介意使用“title”属性的原因是什么,我在 W3C w3schools.com/tags/tag_option.asp 上看不到它,并且不记得真的使用过它。您不能将描述存储在对象中,然后仍然检索该数据,因为这是模型现在绑定的内容? 在您链接到的 W3C 页面上,如果您单击 Global Attributes 链接,您会看到 option 元素支持 title 属性。我使用 title 属性只是为了显示“工具提示”文本,因此如果您将鼠标悬停在某个选项上,您可以获得关于该选项含义的更详细的描述。这是一件小事,但如果可能的话,它会很高兴。 @CharlesO。我想做和你一模一样的事。设置一个对象(非字符串值),但我也想在选项列表中使用标题。有没有办法解决这个问题。我似乎找不到它...【参考方案6】:

如果你使用 md-select 和 ng-repeat md-option 从 angular material 那么你可以添加 ng-model-options="trackBy: '$value.id'" 到 this pen 中显示的 md-select 标签 ash

代码:

<md-select ng-model="user" style="min-width: 200px;" ng-model-options="trackBy: '$value.id'">
  <md-select-label> user ? user.name : 'Assign to user' </md-select-label>
  <md-option ng-value="user" ng-repeat="user in users">user.name</md-option>
</md-select>

【讨论】:

以上是关于使用 AngularJS 和 ng-repeat 初始化选择的主要内容,如果未能解决你的问题,请参考以下文章

使用 angularjs 和 ng-repeat 从 JSON 数据创建表

关于angularjs的ng-repeat指令

AngularJS:使用控制器和 ng-repeat 在 div 上重新加载数据

AngularJS:如何使用自定义指令来取代ng-repeat

ng-repeat 内的 ng-repeat 和每个项目的 td - AngularJS

在 angularjs 中使用 ng-repeat 创建动态表