'$scope not update from AngularJS directive
I implemented custom directive for if select element, in which if there is only one item then it selects that item by default else it works as regular drop down which works fine.
My problem is I have two drop down as cascade. A Company list and a Department list. The Department list depends on a Company list. So when only one Company is selected by default then Department list will also update respectively by default.
For that I try to use ng-change but It does not access updated value it shows old value in log.
My angularjs code is below:
angular.module('TestApp', [
]);
angular.module('TestApp').directive('advanceDropdown', function () {
var directive = {}
directive.restrict = 'A';
directive.require = 'ngModel';
directive.scope = {
items: '=advanceDropdown',
model: '=ngModel',
key: '@key',
change: '&ngChange'
}
directive.link = function (scope, element, attrs, ctrl) {
scope.$watch('items', function (n, o) {
if (scope.items.length == 1) {
scope.model = scope.items[0][scope.key];
scope.change();
}
});
}
return directive;
});
(function () {
'use strict';
angular.module('TestApp').controller('TestCtrl', ['$scope', TestCtrl]);
function TestCtrl($scope) {
$scope.departmentList = [];
$scope.companyList = [];
$scope.designation = new Designation();
$scope.active = null;
$scope.BindDepartments = function () {
console.log('updated companyId:' + $scope.designation.CompanyId);
//Code here
//Load department base on selected company
//$scope.departmentList = data;
}
$scope.GetCompanyById = function (companyId) {
//Get company data by id
//recived from server
$scope.companyList = [{CompanyId:2,CompanyName:'xyz'}];
}
$scope.Init = function () {
$scope.active = null;
$scope.designation = new Designation();
$scope.GetCompanyById(2);
}
}
})();
function Designation() {
this.DesignationId = 0;
this.DesignationName = '';
this.DepartmentId = 0;
this.CompanyId = 0;
}
Designation.prototype = {
constructor: Designation
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.min.js"></script>
<div ng-app="TestApp" ng-controller="TestCtrl">
<select ng-model="designation.CompanyId"
ng-options="dept.CompanyId as dept.CompanyName for dept in companyList"
ng-change="BindDepartments()"
advance-dropdown="companyList" key="CompanyId" required>
<option value="" disabled>--Select Company--</option>
</select>
</div>
In a BindDepartment()
method $scope.designation.CompanyId
value was not updated.
It Show log updated company id:0
I expect updated company id:2
Solution 1:[1]
Avoid using isolate scope with the ng-model controller.
//directive.scope = {
// items: '=advanceDropdown',
// model: '=ngModel',
// key: '@key',
// change: '&ngChange'
//}
directive.scope = false;
Instead use the $setViewValue method to change the model value.
directive.link = function (scope, element, attrs, ctrl) {
scope.$watchCollection(attrs.advanceDropdown, function (n, o) {
if (n && n.length == 1) {
ctrl.$setViewValue(n[0]);
}
});
}
The $setViewValue
method will automatically invoke the ng-change
expression.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | georgeawg |