AngularJS单选按钮不绑定到模型

时间:2015-06-17 19:10:39

标签: javascript angularjs model-view-controller

我在使用AngularJS时遇到了将单选按钮绑定到MVC模型的问题,所有其他字段都成功绑定到MVC模型,但单选按钮只是没有绑定。请告知我的电线混乱的地方。

HTML

<tr ng-repeat="item in experienceModel">
                <td><input type="text" name="StartDate" ng-model="item.StartDate | date:'dd-MM-yyyy'" id="date_teachingStart{{$index}}"/></td>
                <td><input type="text" name="EndDate" ng-model="item.EndDate | date:'dd-MM-yyyy'" id="date_teachingEnd{{$index}}"/></td>
                <td><input type="text" name="SubjectArea" ng-model="item.SubjectArea"/></td>
                <td><input type="text" name="Position" ng-model="item.Position"/></td>
                <td><input type="text" name="Institution" ng-model="item.Institution"/></td>
                <td><input type="text" name="City" ng-model="item.City"/></td>
                <td><input type="text" name="Country" ng-model="item.Country"/></td>
                <td class="centerAlign"><input type="radio" name="item.IsCurrent" value="{{$index}}" ng-model="selected.item" id="radio_experience[{{$index}}]" /></td>                    
                <td><a class="removeRow" title="Delete item" href="" ng-click="removeRow()"></a></td>
                <td><input type="hidden" name="CVId" ng-model="item.CVID" /></td>
                <td><input type="hidden" name="ExperienceID" ng-model="item.ExperienceID" /></td>
            </tr>

脚本

 var experienceModel = <%: Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model.TeachingExperience)) %>
     app.value("experienceModel", experienceModel);

角度控制器

 app.controller('TeachingController', ['$scope', 'experienceModel',
function ($scope, experienceModel) {

        $scope.counter = 0;            

        $scope.selected = {};

        $scope.experienceModel = experienceModel;

        // Set the selected value to reflect initial data 
        $scope.experienceModel.forEach(function (item, index) {
            if (item.IsCurrent) {
                $scope.selected.item = index;
            }
        });

        if ($scope.experienceModel == null) {
            $scope.experienceModel = [{ 'ExperienceID': '', 'CVID': '', 'ExperienceCategoryId': '', 'StartDate': '', 'EndDate': '', 'SubjectArea': '', 'NoOfDays': '', 'Position': '', 'Programme': '', 'KnowledgeArea': '', 'Institution': '', 'Client': '', 'City': '', 'Country': '', 'IsCurrent': '' }];
        }

        if ($scope.experienceModel.length == 0) {
            $scope.experienceModel.push({ 'ExperienceID': '', 'CVID': '', 'ExperienceCategoryId': '', 'StartDate': '', 'EndDate': '', 'SubjectArea': '', 'NoOfDays': '', 'Position': '', 'Programme': '', 'KnowledgeArea': '', 'Institution': '', 'Client': '', 'City': '', 'Country': '', 'IsCurrent': '' });
        }

        $scope.$watch('selected.item', function (index) {
            $scope.items.forEach(function (item, i) {
                item.isCurrent = i === parseInt(index);
            });
        });

        $scope.counter = 1;

    $scope.addRow = function () {
        $scope.experienceModel.push({ 'ExperienceID': '', 'CVID': '', 'ExperienceCategoryId': '', 'StartDate': '', 'EndDate': '', 'SubjectArea': '', 'NoOfDays': '', 'Position': '', 'Programme': '', 'KnowledgeArea': '', 'Institution': '', 'Client': '', 'City': '', 'Country': '', 'IsCurrent': '' });
        $scope.counter++;
    }
    $scope.removeRow = function () {
        var row = $(this);
        $scope.experienceModel.splice(row[0].$index, 1);
        $scope.counter--;
    }
}]);

1 个答案:

答案 0 :(得分:2)

负责AngularJS中双向数据绑定的ng-model 。您应该在希望用户与之交互的所有表单字段上设置此属性。

它会照顾为您设置字段的值,可以这么说 - 因此应删除value属性。您可以 ng-modelvalue ,但如果您决定只设置值(在某些情况下有意义,例如readonly字段),它会仅限于一个方向 - 它将对模型的更改做出反应,但无法更改模型。

好的,在理论介绍之后,这是一个可能的解决方案:

angular.module('app', [])
  .controller('ctrl', function($scope) {

    // Sample data
    $scope.items = [
      {name: 'First', isCurrent: false},
      {name: 'Second', isCurrent: false},
      {name: 'Third', isCurrent: false},
      {name: 'Fourth', isCurrent: false}
    ];

    /* Object to track selected things. (It's better to use objects
     * rather than plain variables to avoid problems with variable's scope) */
    $scope.selected = {};

    // Set the selected value to reflect initial data 
    $scope.items.forEach(function(item, index) {
      if (item.isCurrent) {
        $scope.selected.item = index;
      }
    });

    /* If selected item changes, set corresponding item's 
     * isCurrent property to true and all others to false */
    $scope.$watch('selected.item', function(index) {
      $scope.items.forEach(function(item, i) {
        item.isCurrent = i === parseInt(index);
      });
    });

  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<body ng-app="app" ng-controller="ctrl">
  <ul>
    <li ng-repeat="item in items">
      {{ item.name }}
      <label>
        <input type="radio" ng-model="selected.item" value="{{ $index }}">current
      </label>
    </li>
  </ul>
  <pre>{{ items | json }}</pre>
</body>

好的,所以在合并了这些以及我们在评论中澄清的内容后,您的HTML代码应如下所示:

<!-- (...) -->
<td><input type="text" name="city" ng-model="item.City" /></td>
<td><input type="text" name="country" ng-model="item.Country" /></td>
<td class="centerAlign"><input type="radio" ng-model="selected.item" /></td>
<td><a class="removeRow" title="Delete item" href="" ng-click="removeRow($index)"></a></td>
<!-- (...) -->

注意一些“奖励”改进:

  • 使用AngularJS时无需使用href="javascript:void(0)" href=""就足够了(https://docs.angularjs.org/api/ng/directive/a
  • 删除行时,最简单的方法是将迭代的$index 传递给removeRow()函数
  • 如果您不使用Angular的验证,则不需要name属性
  • 如果您没有使用标签(特别是<label for="sth" >),那么您将不会id属性