Reputation: 2078
So i have this simple listing of system users (attached screenshot), client can edit the users or create new user and a new panel is displayed accordingly.
What I'm doing is updating the different fields of the edit/create form depending on the user action. But since im coming from a Backbone background, the usual way I would do something like this is to create a new view, initialize it with a parameter indicating whether it's a create or edit mode, and then destroy this view when clicking on cancel/save changes/create user. But right now im just depending on angular event binding to update the same form elements, is this the proper way to do it in angular?
$scope.prepare_form = function (user_id) {
if (user_id) {
// edit mode
var user = filterFilter($scope.users, { id: user_id })[0];
$scope.fdata_create.name = user.name;
$scope.fdata_create.email = user.email;
$scope.fdata_create.role_name = user.role_name;
$scope.fdata_create.id = user.id;
} else {
// create mode
$scope.fdata_create.name = '';
$scope.fdata_create.email = '';
$scope.fdata_create.role_name = '';
$scope.fdata_create.id = '';
}
$scope.form_create_open = true;
}
Upvotes: 3
Views: 703
Reputation: 52837
I would reuse the same form, but bind to different models:
app.controller('ctrl', function($scope){
$scope.addUser = function(){
$scope.add= true;
$scope.user = {};
};
$scope.editUser =function(user){
$scope.add=false;
$scope.user ={};
angular.copy($scope.user, user);
};
$scope.onOK = function(user){
...
angular.copy(user, $scope.user);
};
});
HTML:
<div ng-controller="ctrl">
<form>
<input type ="text" ng-model="user.name" />
<input type="text" ng-model="user.role" />
<button ng-click="onOK(user)"> ok </button>
</form>
</div>
Upvotes: 2
Reputation: 22697
You should think based on Models rather than forms. You should create Teammate model with its sync methods, update, create, replace, etc. It is cleaner, here is example extract from this tutorial
Book html form.
<div ng-controller="BookController">
<div ng-style="{ backgroundImage: 'url(' + book.getImageUrl(100, 100) + ')' }"></div>
Id: <span ng-bind="book.id"></span>
<br/>
Name:<input type="text" ng-model="book.name" />
<br/>
Author: <input type="text" ng-model="book.author" />
<br/>
Is Available: <span ng-bind="book.isAvailable() ? 'Yes' : 'No' "></span>
<br/>
<button ng-click="book.delete()">Delete</button>
<br/>
<button ng-click="book.update()">Update</button>
</div>
Book Model define as factory.
app.factory('Book', ['$http', function($http) {
function Book(bookData) {
if (bookData) {
this.setData(bookData):
}
// Some other initializations related to book
};
Book.prototype = {
setData: function(bookData) {
angular.extend(this, bookData);
},
load: function(id) {
var scope = this;
$http.get('ourserver/books/' + bookId).success(function(bookData) {
scope.setData(bookData);
});
},
delete: function() {
$http.delete('ourserver/books/' + bookId);
},
update: function() {
$http.put('ourserver/books/' + bookId, this);
},
getImageUrl: function(width, height) {
return 'our/image/service/' + this.book.id + '/' + width + '/' + height;
},
isAvailable: function() {
if (!this.book.stores || this.book.stores.length === 0) {
return false;
}
return this.book.stores.some(function(store) {
return store.quantity > 0;
});
}
};
return Book;
}]);
Book controller that uses Book Model
app.controller('BookController', ['$scope', 'Book', function($scope, Book) {
$scope.book = new Book();
$scope.book.load(1);
}]);
If you want to update book name for example, you dont need to manually assign the new name because the Book's name instance is binded to ng-model attribute. To update it just only need call your update function from Book Factory.
$scope.book = new Book();
if(book_id){
$scope.book.load(book_id);
$scope.submit_book = $scope.book.update // submit_book function need to be triggered after submit the form. Here it
}
else{
$scope.submit_book = $scope.book.create // submit_book function need to be triggered after submit the form. Here it will create the book
}
Upvotes: 2