patternjavascriptMinor
Avoid jQuery in click event
Viewed 0 times
clickjqueryeventavoid
Problem
I have the following controller:
for the following HTML:
Everything works fine:
In the form, I search for the user, then I am getting a user list in the format
The questions are now:
-
My click event looks ugly (I use jQuery). What would be the angular way to perform this?
angular.module("UserRoles")
.controller("UserRolesController", function($http, $scope){
$scope.usersearch = "";
$scope.users = [];
$scope.roles = {
}
$scope.getusers = function(){
$http.get("/api/finduser/"+$scope.usersearch)
.success(function(data){
$scope.users = data;
});
}
// returns ([ [username, userid], ... ])
$scope.getroles = function($event){
var uid = $($event.currentTarget).find("a").data("userid");
$http({
"method": "GET",
"url":"/api/rolesbyuser/",
"params": {"user_dn": uid}
}).success(function(data){
console.log(data);
$scope.roles = data;
});
// returns {ldapuser: ldapusername, direct_roles: [r1, r2], inheritedroles: [ir1ir2]}
};
});for the following HTML:
User Suchen: {{ usersearch }}
{{ user[0] }}
{{ roles.ldapuser }}
Direkte Rollen
{{ role }}
Vererbte Rollen
{{ role }}
Everything works fine:
In the form, I search for the user, then I am getting a user list in the format
[[user, id] ...] . The site presents the user name and the id is saved in the data attribute of the user. If one clicks on one of the users on the left side, angular fetches the roles for the according user and displays them.The questions are now:
-
My click event looks ugly (I use jQuery). What would be the angular way to perform this?
$($event.currentTarget).find("a").data("userid")- Is there an even
Solution
You can access the data by simply passing it into your method call. So instead of passing an event to
Replace your template:
Then update your function:
Using a Service
Sometimes it's good to separate your
Each method in the service will return a
The bonus of this is that it makes it easier to test your controller as you can easily mock out the service. You could've mocked out the
I would also recommend having the userSearch being passed into
getroles, just pass the value.Replace your template:
{{ user[0] }}
Then update your function:
$scope.getroles = function(uid){
$http({
"method": "GET",
"url":"/api/rolesbyuser/",
"params": {"user_dn": uid}
}).success(function(data){
console.log(data);
$scope.roles = data;
});
// returns {ldapuser: ldapusername, direct_roles: [r1, r2], inheritedroles: [ir1ir2]}
};Using a Service
Sometimes it's good to separate your
$http calls to a service. This allows you to re-use your $http calls in other controllers. It seems like overkill, but it helps with re-use. Alternatively, you could use the $resource, which will build the service for you automatically. Unfortunately, in your case, your endpoints are different, so you'll need to roll your own service.Each method in the service will return a
promise so that future controllers can customize the success conditions.The bonus of this is that it makes it easier to test your controller as you can easily mock out the service. You could've mocked out the
$http service, but then your implementation would start to leak into your tests.I would also recommend having the userSearch being passed into
getUser as a parameter. This reduces the amount of state that your controller needs to maintain.angular.module("UserRoles")
.service("UserRolesService", function($http) {
this.getUsers = function(userId) {
return $http.get("/api/finduser/" + userId);
}
this.getRoles = function(uid) {
return $http.get("/api/rolesbyuser/", { params : { "user_dn" : uid } });
}
})
.controller("UserRolesController", function($scope, UserRolesService) {
$scope.usersearch = "";
$scope.users = [];
$scope.roles = {};
$scope.getUsers = function(userId) {
UserRolesService.getUsers(userId).success( function(data) {
$scope.users = data;
});
};
$scope.getRoles = function(uid) {
UserRolesService.getRoles(uid).success(function(data) {
console.log(data);
$scope.roles = data;
});
};
});Code Snippets
<ul class="list-group">
<li class="list-group-item text-center user-item"
ng-repeat="user in users"
ng-click="getroles(user[1])">
<a href="" data-userid="{{ user[1] }}">
{{ user[0] }}
</a>
</li>
</ul>$scope.getroles = function(uid){
$http({
"method": "GET",
"url":"/api/rolesbyuser/",
"params": {"user_dn": uid}
}).success(function(data){
console.log(data);
$scope.roles = data;
});
// returns {ldapuser: ldapusername, direct_roles: [r1, r2], inheritedroles: [ir1ir2]}
};angular.module("UserRoles")
.service("UserRolesService", function($http) {
this.getUsers = function(userId) {
return $http.get("/api/finduser/" + userId);
}
this.getRoles = function(uid) {
return $http.get("/api/rolesbyuser/", { params : { "user_dn" : uid } });
}
})
.controller("UserRolesController", function($scope, UserRolesService) {
$scope.usersearch = "";
$scope.users = [];
$scope.roles = {};
$scope.getUsers = function(userId) {
UserRolesService.getUsers(userId).success( function(data) {
$scope.users = data;
});
};
$scope.getRoles = function(uid) {
UserRolesService.getRoles(uid).success(function(data) {
console.log(data);
$scope.roles = data;
});
};
});Context
StackExchange Code Review Q#92146, answer score: 4
Revisions (0)
No revisions yet.