我有一个非常简单的CRUD应用程序来管理音乐专辑。只跟踪了两个字段,标题和艺术家。
在this example中,下拉列表会显示相册列表,如果我填写表单并单击“保存”,则会将其添加到列表中。
在second example中,选择一个相册将填充表单,以便进行编辑和更新。
我的问题是,有没有办法以同一形式获得两种功能?当然,我可以创建两个相同的表单并让它们执行稍微不同的操作,但是如果它们在相同的数据上运行,那么如果选择current_album
,它会更新,以及{{1}时更好选中,它会创建。
主要障碍似乎是与ng-model相比的价值。我可以设置值,以便在我从"New album..."
中选择项目时填充,或者我可以设置<select>
,但不是我所知道的。
答案 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中查看对象的更改。