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

时间:2016-09-30 22:53:54

标签: javascript angularjs angularjs-directive angular-material

我使用md-select,需要在值更改时触发某些代码(构建国家/州/州选择器)。我通过控件更改值时工作正常,但是当模型从代码更改时,我还需要让控件正确反映值。我使用ng-change来触发更改代码(需要更改,因为用户可以在不点击的情况下更改键盘上的值)。问题是,当从代码更改值时,事件不会被触发。为了使事情更复杂一点,md-choose住在一个指令中,允许我在几个地方使用设置。

这是我的指示模板:

<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个用例。

1 个答案:

答案 0 :(得分:3)

你可以使用$ scope。$ watch

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