$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

Plunker demo

避免将隔离作用域与 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 表达式。