AngularJs:如何根据模型设置单选按钮的选中状态

67

我有一个模型在storeLocations对象中返回,其中包含isDefault值。如果isDefault返回true,则我希望将该组中的单选按钮设置为已选中。

不确定是否需要使用$each(data,function(index,value)迭代遍历每个返回的对象,或者是否有更容易使用angular结构进行此操作的方法。

对象:

storeLocations = [
 {
  ... more values,
  isDefault: true
 }
]

标记语言:

    <tr ng-repeat="location in merchant.storeLocations">
        <td>{{location.name}}</td>
        <td>{{location.address.address1}}</td>
        <td>{{location.address.address2}}</td>
        <td>{{location.address.city}}</td>
        <td>{{location.address.stateProvince}}</td>
        <td>{{location.address.postalCode}}</td>
        <td>{{location.address.country}}</td>
        <td>{{location.website}}</td>
        <td>{{location.zone}}</td>
        <td><input type="radio" ng-model="location.isDefault" value="{{location.isDefault}}" name="isDefault_group"></td>

你是否需要在每个商店位置对象上添加isDefault属性?似乎将该属性从每个对象中删除并仅拥有一个单一的storeDefault属性可能更容易。然后,使用<input ... ng-model="storeDefault" value="{{location.id}}">。当然,这假设/要求每个位置都有一个包含唯一值的字段(例如id)。 - Mark Rajcok
我喜欢你提出的数据结构更好,但当返回storeLocation对象时,我仍需要将默认存储显示为已选中。 - Christopher Marshall
考虑到这个问题是在2013年提出的,如果有什么的话,你链接的答案应该被标记为重复。 - Christopher Marshall
6个回答

76

使用ng-value代替value

ng-value="true"

使用ng-checked的版本由于代码重复而更糟糕。


1
这是最近发布的吗?我觉得在我使用的那个版本中还没有这个功能。 - Christopher Marshall
我使用的是AngularJS v1.1.5版本。 - ivan.a.bovin
3
这是正确答案。使用'ng-value'和'ng-model'正确地选中/取消选中按钮并保持双向绑定。 - DhafirNz
@DhafirNz 刚刚又用了一次,改成了正确的答案。 - Christopher Marshall
8
对我来说不起作用,相反 ng-checked 起作用了。 - TooCool
我也是一样。对我来说,唯一有效的是ng-checked。不是ng-model也不是ng-value。 - Agorreca

61
如果您有一组单选按钮并希望根据模型设置单选按钮的选中状态,则具有相同valueng-model的单选按钮将自动被选中。
<input type="radio" value="1" ng-model="myRating" name="rating" class="radio">
<input type="radio" value="2" ng-model="myRating" name="rating" class="radio">
<input type="radio" value="3" ng-model="myRating" name="rating" class="radio">
<input type="radio" value="4" ng-model="myRating" name="rating" class="radio">
如果myRating的值为"2",那么第二个单选按钮将被选中。

当模型为空时,如何设置第一个选项为默认选中?我尝试了ng-checked和ng-init但都不起作用。有什么想法吗? - hogan
1
你好,为什么你没有在控制器加载或ng-init方法中设置模型的默认值?如果你在控制器加载时设置模型的默认值,比如“myRating”=1,那么第一个单选按钮将会被选中。 - Rubi saini
2
Angular的哪个版本?至少在1.2版本中,ng-model与"value"结合使用时,在页面加载时不会将单选按钮之一设置为选中状态。只有在选择一个选项后,双向绑定才开始起作用。编辑:实际上,它适用于数字,但如果值是字符串,则不适用。 - tandrewnichols
@tandrewnichols 我在页面加载时遇到了单选按钮未被初始选择的问题(尽管我可以看到该单选按钮的ng-model和ng-value相同),结果发现其中一个值是数字,而另一个值是字符串,因此Angular(不幸地现在使用===)确定它们不相等。我只需在获取其中一个值时将其包装在Number()中,一切都很好。我也看到过一个Plunkr(抱歉,我丢失了URL),显示这也适用于字符串。哦,还要使用'ng-value'而不是'value'! - Roger

28

我认为更加强大并且避免在所有模型中使用isDefault的一种方法是使用ng属性 ng-modelng-valueng-checked

ng-model:绑定值到您的模型。

ng-value:传递给ng-model绑定的值。

ng-checked:被评估的值或表达式。对于单选按钮和复选框很有用。

使用示例: 在以下示例中,我有我的模型以及支持我网站的语言列表。要显示不同支持的语言并更新选择语言的模型,我们可以这样做。

<!-- Radio -->
<div ng-repeat="language in languages">

  <div>
    <label>

      <input ng-model="site.lang"
             ng-value="language"
             ng-checked="(site.lang == language)"
             name="localizationOptions"
             type="radio">

      <span> {{language}} </span>

    </label>
  </div>

</div>
<!-- end of Radio -->

我们的模型 site.lang 将会在表达式 (site.lang == language) 为真时得到一个 language 值。这将使您可以轻松地将其与服务器同步,因为您的模型已经发生了更改。


22

最终只使用了内置的angular属性ng-checked="model"


2
这很奇怪。添加 checked="checked" 没有效果,但 ng-checked="true" 却有效了,而且它所做的唯一一件事就是将 checked="checked" 添加到单选按钮中。 - ivkremer
1
我的模型当时是一个布尔值,所以对我来说很有效:\ - Christopher Marshall
@Kremchik 这是由于Angular的循环引用导致的。它首先在HTML解析期间搜索指令,然后在DOM上分配事件监听器和$watch-es模型之后编译所有内容,这也涉及在您的HTML标记上生成属性。这就是为什么如果您使用[code]checked="checked"[/code],Angular将简单地覆盖它,因为正如Angular团队所说:“Angular喜欢控制您的DOM”。希望它能解释一下行为。 - Mark Karwowski

2

如在问题评论中所讨论的,以下是一种可能的解决方法:

  • 当您首次检索数据时,请循环遍历所有位置并将storeDefault设置为当前默认的商店。
  • 在标记中:<input ... ng-model="$parent.storeDefault" value="{{location.id}}">
  • 在保存数据之前,请循环遍历所有merchant.storeLocations并将isDefault设置为false,除了location.id与storeDefault相等的商店。

以上假设每个位置都有一个字段(例如id),该字段包含唯一值。

请注意,$parent.storeDefault被使用,因为ng-repeat创建了一个子作用域,我们希望在父作用域上操作storeDefault参数。

Fiddle


1

只需像这样做,<input type="radio" ng-disabled="loading" name="dateRange" ng-model="filter.DateRange" value="1" ng-checked="(filter.DateRange == 1)"/>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接