angularjsangularjs-ng-change

Responding to drop down selection change in angular without model binding


I have a drop down that should cause a data fetch on change. I don't need two way binding to a model for the drop down. I just want it initially populated with a list of departments and when a user selects one, it gets the list of users in that department.

The select looks like this:

<select class="form-control" id="selDepartmentList" ng-model="departmentList" ng-change="getUsersInDepartment(document.getElementById("selDepartmentList").options[document.getElementById("selDepartmentList").selectedIndex].value)">
        <option value="-1">All</option>
        <option ng-repeat="dept in departmentList"
                value="{{dept.DepartmentId}}">
                {{dept.DepartmentName}}
        </option>
</select>

I tried ng-change without ng-model, but it fails since ng-change requires ng-model for some reason. I tried setting ng-model to null and empty string, but neither worked. I also tried not using ng-change at all and using onchange, but getUsersInDepartment can't be found through onchange since it's attached to my controller. With ng-model set to departmentList, the drop down won't hold a value, any selection is erased.

All I want to have happen is that when a user selects a department it passes the id for that department to getUsersInDepartment, which will then fetch the user list. But right now getUsersInDepartment is never called.

departmentList is defined in my controller and attached to $scope. All the examples I've seen have some kind of selectedModelObject that they bind to the drop down. I don't have one of those.

My controller looks like:

controller('AdminTableCtrl', function ( $scope, coreAPIservice ) {
    $scope.userList = [];
    $scope.departmentList = [];

    coreAPIservice.GetUserList().success(function (response) {
        $scope.userList = response;
    });

    coreAPIservice.GetDepartmentList().success(function (response) {
        $scope.departmentList = response;
    });

    $scope.getUsersInDepartment = function(deptId) {
        if(deptId === -1) {
            coreAPIservice.GetUserList().success(function (response) {
                $scope.userList = response;
            });
        }
        else {
            coreAPIservice.GetUsersInDepartmentList(deptId).success(function (response) {
                $scope.userList = response;
            });
        }
    }
});

Edit:

My original attempt with ng-options:

<select class="form-control" id="selDepartment"
                                        ng-model="selectedDepartment"
                                        ng-options="dept as dept.DepartmentName for dept in departmentList track by dept.DepartmentId">
            <option value="">Select Team...</option>
</select>

selectedDepartment is defined as:

$scope.selectedDepartment = {};

Solution

  • The solution is to avoid decorating the <select> element with any angular directives and instead place ng-click on each <option>.

    Like this:

    <select class="form-control" id="selDepartmentList">
            <option value="-1" selected>All</option>
            <option ng-repeat="dept in departmentList"
                                    ng-click="getUsersInDepartment(dept.DepartmentId)"
                                    value="{{dept.DepartmentId}}">
                                    {{dept.DepartmentName}}
            </option>
    </select>