javascript - 当模型更改时如何在 md-select 上触发 ng-change ?

标签 javascript angularjs angularjs-directive angular-material

我正在使用 md-select,并且需要在值更改时触发某些代码(构建国家/州选择器)。当我通过控件更改值时,它工作正常,但当模型从代码更改时,我还需要让控件正确反射(reflect)值。我正在使用 ng-change 来触发更改代码(需要 ng-change 因为用户可以从键盘更改值而无需单击它)。问题是,当代码中的值发生更改时,该事件不会被触发。让事情变得更复杂的是,md-selects 存在于指令中,允许我在多个地方使用该设置。

这是我的指令模板:

<md-input-container class="md-block">
    <label>Country</label>
    <md-select name="country" ng-model="countryState.countryModel" ng-change="countryState.onCountrySelected()">
        <md-option ng-repeat="country in countryState.countries" ng-value="country.itemId">
            {{ country.name | translate }}
        </md-option>
    </md-select>
</md-input-container>

<md-input-container class="md-block">
    <label>State</label>
    <md-select name="state" ng-model="countryState.stateModel" ng-disabled="countryState.countryModel == null">
        <md-option ng-repeat="state in countryState.states" ng-value="state.itemId">
            {{ state.name | translate }}
        </md-option>
    </md-select>
</md-input-container>

这是指令代码:

angular.module('myapp.shared')

    .directive('countryStateInput', [function () {
        return {
            restrict: 'E',
            templateUrl: 'app/shared/inputs/countryState/country-state-input.directive.html',
            transclude: false,
            scope: {
                coordsForm: '=',
                countryModel: '=',
                stateModel: '='
            },
            bindToController: true,
            controllerAs: 'countryState',
            controller: ['$scope', '$document', 'OptionService', function($scope, $document, OptionService) {
                var ctrl = this;

                // Properties
                ctrl.countries = null;
                ctrl.states = [];
                ctrl.selectedCountryIndex = null;

                ctrl.onCountrySelected = function() {
                    // Get the index of the country
                    for (var i = 0; i < ctrl.countries.length; i++) {
                        if (ctrl.countryModel === ctrl.countries[i].itemId) {
                            // If a different country was chosen, clear the selected state
                            if (i !== ctrl.selectedCountryIndex) {
                                ctrl.stateModel = null;
                                angular.copy(ctrl.countries[i].states, ctrl.states);
                            };

                            // Save the index of the selected country
                            ctrl.selectedCountryIndex = i;
                            return;
                        }
                    }
                };

                // Initialization
                var initialize = function () {
                    OptionService.getCountries().then(
                        function (result) {
                            ctrl.countries = result;
                        });
                };

                (function () {
                    $document.ready(function () {
                        initialize();
                    })
                })();
            }]
        }
    }]);

这是一个使用示例:

<country-state-input country-model="app.location.countryId" state-model="app.location.stateId" input-form="locationsForm"></country-state-input>

OptionService.getCountries() 返回类似这样的内容(状态列表已缩短):

[
    {
        "itemId": 1,
        "name": "CA",
        "states": [
            {
                "itemId": 1,
                "name": "CA_ON",
                "abbreviation": "ON"
            },
            {
                "itemId": 2,
                "name": "CA_QC",
                "abbreviation": "QC"
            }
        ]
    },
    {
        "itemId": 2,
        "name": "US",
        "states": [
            {
                "itemId": 14,
                "name": "US_AL",
                "abbreviation": "AL"
            },
            {
                "itemId": 15,
                "name": "US_AK",
                "abbreviation": "AK"
            }
        ]
    }
]

基本上,我试图弄清楚是否有一种方法可以触发 onCountrySelected 来覆盖所有 3 个用例。

最佳答案

你可以使用$scope.$watch

$scope.$watch(
   function valueGetter(){
      return smth;
   },
   function onChange(newSmth, oldSmth){
   }
)

关于javascript - 当模型更改时如何在 md-select 上触发 ng-change ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39801180/

相关文章:

javascript - 为什么 ng-click 不会在组件模板中触发?

angularjs - 无法弄清楚如何使用 $parsers 和 $formatters 创建指令

javascript - 异步函数执行顺序

javascript - 使用 javascript/jQuery 更改 JSON 数据的图像源

javascript - Angular 1 TypeScript 项目中的依赖注入(inject)

javascript - Angular $q在http请求之前执行 "then"

AngularJS 提前输入 + 多选标签

javascript - 显示/隐藏 JavaScript 的问题

javascript - 将 Javascript 代码转换为 Delphi

javascript - 更新范围时不会调用 Angular 指令