#javascript #angularjs #angularjs-directive #angular-material
#javascript #angularjs #angularjs-директива #angular-материал
Вопрос:
Я использую md-select и должен запускать определенный код при изменении значения (создание селектора страны / состояния). У меня все работает нормально, когда я меняю значение с помощью элемента управления, но мне также нужно, чтобы элементы управления правильно отражали значения при изменении модели из кода. Я использую 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 = resu<
});
};
(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:
Вы могли бы использовать $scope. $watch
$scope.$watch(
function valueGetter(){
return smth;
},
function onChange(newSmth, oldSmth){
}
)
Комментарии:
1. Спасибо, Валерий! На самом деле я пробовал смотреть на ctrl.CountryModel, который не работал, но ввод функции valueGetter там работал.