【问题标题】:Radio button two-way binding issue with ng-modelng-model 的单选按钮双向绑定问题
【发布时间】:2014-11-05 19:45:41
【问题描述】:

我在使用 ng-model 和 ng-value 进行单选按钮双向绑定时遇到问题。我有三个单选按钮,在 ng-repeat 中创建。它们都是相同的 ng-model,$scope.selectedItem,每个按钮的 ng-value 都是 ng-repeat 中的当前项。这似乎工作正常。当我想在控制器中设置所选项目时,问题就来了。这里我有一个 ng-click 事件 select() 将 selectedItem 设置为传入的项目。

function MyCtrl($scope) {
    $scope.list = [{
        id: 1
    }, {
        id: 2
    }, {
        id: 3
    }];
    $scope.select = function (item) {
        $scope.selectedItem = item;
    }
}
<div ng-repeat="item in list" class="interactive" ng-click="select(item)">
    <input type="radio" name="itemSelector" ng-model="selectedItem" ng-value="item" />     
  {{item.id}}
</div>

只要我只使用 ng-click 事件选择项目,它就可以工作。如果我直接使用单选按钮单击 #1,然后使用 ng-click 事件选择 #2,然后为 #1 触发 ng-click 事件,则第二个单选按钮将被取消选中,但第一个单选按钮不会被选中。当我在调试器中观察时,我可以看出 selectedItem 的值设置成功,只是单选按钮没有更新。

我使用单选按钮绑定的方式有问题吗?有没有办法解决这个问题?

JSFiddle:https://jsfiddle.net/SamGraber/vscvxg40/4/

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    绝对是一种奇怪的行为。我不确定是什么导致了您的问题,但请在此处查看解决方法 https://jsfiddle.net/vscvxg40/9/

    请注意,无论如何这是推荐的 HTML 做法 - 包装器 div 现在是 label,它会在单击时触发单选。

    【讨论】:

    • @SebastienPiu 是正确的,根本问题是继承的父范围中的模型在第一次从子范围设置后被子范围遮挡。
    • 该解决方案运行良好,但使用 ng-click 事件触发单选按钮背后的想法是,我可以在 div 样式上将其用作表格行。以同样的方式使用标签似乎有点 hacky。有什么想法吗?
    • @SamGraber 我在下面采纳了 Sebastien 的想法并将其应用于您的代码 jsfiddle.net/vscvxg40/10。现在,虽然ng-repeat 创建了一个子作用域,inputs 引用父作用域的selectedItem 作为它的ng-model。由于divinput 现在都引用了相同的模型,因此不会出现您之前看到的冲突。
    【解决方案2】:

    ng-repeat 创建一个子作用域,所以你只需要将 ng-model 绑定到$parent 作用域。完全不需要ng-click,因为 ng-model 已经为你做了双向绑定。在这里看小提琴http://jsfiddle.net/d1570gfk/1/

    <div ng-repeat="item in list" class="interactive">
        <input type="radio" name="itemSelector" ng-model="$parent.selectedItem" ng-value="item" /{{item.id}}
    </div>
    

    【讨论】:

      【解决方案3】:

      这是一个解决您问题的小提琴 http://jsfiddle.net/paila/7ax5tspc/

      问题在于 selectedItem 变量在控制器范围内的范围。

      当使用 ng-repeat 生成单选按钮并更改 selectedItem 时,会在每个子作用域上创建一个新变量,并且永远不会修改控制器作用域上的 selectedItem。

      使用对象来保存所选项目的值将解决此问题。当您这样做时,子作用域可以覆盖对象属性并将它们反射回父控制器作用域。

          var myApp = angular.module('myApp', []);
      
          function MyCtrl($scope) {
              $scope.list = [{
                  id: 1
              }, {
                  id: 2
              }, {
                  id: 3
              }];
              $scope.selected = {};
              $scope.selected.Item = $scope.list[0];
          }
      

      【讨论】:

      • 这不能回答问题。点击input 不是问题。
      猜你喜欢
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      • 2017-06-24
      • 2015-09-11
      • 2017-05-22
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多