$scope 未从 AngularJS 指令更新
$scope not update from AngularJS directive
我为 if select 元素实现了自定义指令,其中如果只有一个项目,那么默认情况下 select 就是那个项目,否则它作为常规下拉列表工作,效果很好。
我的问题是我有两个级联下拉列表。公司列表和部门列表。部门列表取决于公司列表。因此,当默认只有一个公司 select 时,部门列表也会默认分别更新。
为此我尝试使用 ng-change 但它不访问更新值它在日志中显示旧值。
我的 angularjs 代码如下:
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>
在 BindDepartment()
方法中 $scope.designation.CompanyId
值未更新。
It Show log updated company id:0
I expect updated company id:2
避免将隔离作用域与 ng-model 控制器一起使用。
//directive.scope = {
// items: '=advanceDropdown',
// model: '=ngModel',
// key: '@key',
// change: '&ngChange'
//}
directive.scope = false;
而是使用 $setViewValue 方法更改模型值。
directive.link = function (scope, element, attrs, ctrl) {
scope.$watchCollection(attrs.advanceDropdown, function (n, o) {
if (n && n.length == 1) {
ctrl.$setViewValue(n[0]);
}
});
}
$setViewValue
方法将自动调用 ng-change
表达式。
我为 if select 元素实现了自定义指令,其中如果只有一个项目,那么默认情况下 select 就是那个项目,否则它作为常规下拉列表工作,效果很好。
我的问题是我有两个级联下拉列表。公司列表和部门列表。部门列表取决于公司列表。因此,当默认只有一个公司 select 时,部门列表也会默认分别更新。
为此我尝试使用 ng-change 但它不访问更新值它在日志中显示旧值。
我的 angularjs 代码如下:
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>
在 BindDepartment()
方法中 $scope.designation.CompanyId
值未更新。
It Show log updated company id:0
I expect updated company id:2
避免将隔离作用域与 ng-model 控制器一起使用。
//directive.scope = {
// items: '=advanceDropdown',
// model: '=ngModel',
// key: '@key',
// change: '&ngChange'
//}
directive.scope = false;
而是使用 $setViewValue 方法更改模型值。
directive.link = function (scope, element, attrs, ctrl) {
scope.$watchCollection(attrs.advanceDropdown, function (n, o) {
if (n && n.length == 1) {
ctrl.$setViewValue(n[0]);
}
});
}
$setViewValue
方法将自动调用 ng-change
表达式。