Angular - 使用相同的表单来创建和更新

时间:2014-02-26 10:02:20

标签: javascript angularjs

我有一个非常简单的CRUD应用程序来管理音乐专辑。只跟踪了两个字段,标题和艺术家。

this example中,下拉列表会显示相册列表,如果我填写表单并单击“保存”,则会将其添加到列表中。

second example中,选择一个相册将填充表单,以便进行编辑和更新。

我的问题是,有没有办法以同一形式获得两种功能?当然,我可以创建两个相同的表单并让它们执行稍微不同的操作,但是如果它们在相同的数据上运行,那么如果选择current_album,它会更新,以及{{1}时更好选中,它会创建。

主要障碍似乎是与​​ng-model相比的价值。我可以设置值,以便在我从"New album..."中选择项目时填充,或者我可以设置<select>,但不是我所知道的。

2 个答案:

答案 0 :(得分:6)

您不应该将value属性与ng-model一起使用。这是一种非常糟糕的做法。

我建议您在列表中使用ng-change并使用编辑值保留克隆对象。

$scope.onChange = function() {
  if ($scope.currentAlbum) {
    $scope.editing.title = $scope.currentAlbum.title;
    $scope.editing.artist = $scope.currentAlbum.artist;
  } else {
    $scope.editing = {};
  }
};

保存时需要做的就是检查是否为新对象:

$scope.addOrSaveAlbum = function() {
  if ($scope.currentAlbum) {
    $scope.currentAlbum.title = $scope.editing.title;
    $scope.currentAlbum.artist = $scope.editing.artist;
  } else {
    $scope.albums.push({ title: $scope.editing.title, artist: $scope.editing.artist });
  }

  $scope.editing = {};
};

请参阅http://jsfiddle.net/4Zeuk/12/

(感谢Wawy指出ng-change而不是$scope.$watch

答案 1 :(得分:1)

您确实可以在不需要两种不同形式的情况下获得这两种功能,但是对于选择和表单字段,您不能在ng-model的范围内使用相同的对象。

但你可以做的是在范围内有两个不同的对象,一个包含所选项目的值,另一个包含一个新的专辑实例或所选择的一个副本。然后,当您单击保存/更新按钮时,根据表单中对象的ID,您可以决定是否需要保存或修改相册集。

这是我刚刚解释过的一种方式:

<div ng-app="albumShelf">
<div ng-controller="MainCtrl">
  <div style="float:left;">
    <select ng-options="b.title for b in albums" ng-model="current_album" ng-change=updateForm()>
      <option value="">Choose album...</option>
    </select>
  </div>

  <div style="float:left;">
      <form>
        <input type="text" ng-model="newAlbum.title">
        <br>
        <input type="text" ng-model="newAlbum.artist">
        <br>
        <input type="submit" value="{{ current_album ? 'Update' : 'Save' }}" ng-click="modifyAlbumCollection()">
      </form>
  </div>
</div>

var albumShelf = angular.module('albumShelf', [/*'ngResource'*/])
.controller('MainCtrl', ['$scope', function($scope/*, albumFactory*/) {
    //$scope.albums = albumFactory.query();

    $scope.albums = [
        { id: 1, title: 'Disorganized Fun', artist: 'Ronald Jenkees' },
        { id: 2, title: 'Secondhand Rapture', artist: 'MS MR' }
    ];

    $scope.modifyAlbumCollection = function() {
        if ($scope.newAlbum.id !== null) {
            //We are modifying an existing album
            var i, found = false;
            for (i = 0; i<$scope.albums.length && !found; i++) {
                if ($scope.albums[i].id === $scope.newAlbum.id) {
                    $scope.albums[i] = angular.copy($scope.newAlbum);
                    found = true;
                }
            }
        } else {
            //We are adding a new album to the collection
            $scope.newAlbum.id = $scope.albums.length;
            $scope.albums.push(angular.copy($scope.newAlbum));
            $scope.newAlbum = { id: null, title: '', artist: '' };
        }
    };

    $scope.updateForm = function() {
        if ($scope.current_album) {
            //Copy the information from the selected album into the form.
            $scope.newAlbum = angular.copy($scope.current_album);
        } else {
            //Clear previous album info.
            $scope.newAlbum = { id: null, title: '', artist: '' };
        }
    };
}])
//.factory('albumFactory', function($resource) {
//    return $resource('/albums/:albumId.json', { albumId: '@id' }
//    );
//});

以下是jsfiddle

在我看来,如果你在选择中使用ng-change而不是在ng-model值上使用$ watch,那就更清楚了。因为您想要的是在从下拉列表中选择新值时更新表单,而不是在$ scope中查看对象的更改。