Я хочу изменить значение ng-model (degree) в id (degree_id) в моем шаблоне следующим образом:
<md-select flex class="md-select-form" ng-model="education.degree" placeholder="Degree" save-id required-param="{{education.degree_id}}">
<md-option ng-value="degree" ng-repeat="degree in ['High School', 'Associates Degree', 'Bachelor Degree', 'Masters Degree', 'M.B.A', 'M.D', 'Ph.D', 'other']">{{degree}}</md-option>
</md-select>
Я использовал директиву (save-id) для этого разбора в моем контроллере, и я вытащил данные службы степени и привязал соответствующий идентификатор. Следующий код
.directive('saveId', function(Profile){
return {
require: 'ngModel',
scope: {
requiredParam:'@'
},
link: function(scope, element, attrs, ngModel) {
console.log("initial loading");
// view --> model (change to string)
ngModel.$parsers.push(function(viewValue){
var id = -1;
var keepGoing = true;
Profile.getDegreeList().then(function(data) {
angular.forEach(data, function(ob){
if(keepGoing) {
if(ob.degree == viewValue){
id = ob.degree_id;
keepGoing = false;
}
}
});
//console.log(id); // it gives updated value
});
console.log(id); // it gives -1
return id;
});
}
};
})
Я обновил значение модели, как упоминалось выше, проблема заключается в том, что только обновленное значение доступно в пределах
Profile.getDegreeList() {}
Из этой функции значение -1, что здесь не так? Пожалуйста, дайте мне решения?
Это потому, что ваш вызов Profile.getDegreeList()
является асинхронным.
console.log(id)
вне блока getDegreeList
выполняется сразу, что означает, что он регистрирует определенное значение -1.
console.log(id)
внутри блока getDegreeList
работает, потому что в этот момент данные загружаются.
Вы должны работать с обещаниями ($ q).
Я не уверен, что вы пытаетесь сделать, но просто попробуйте: можно легко использовать атрибут value option, чтобы присвоить значение id выпадающему, а не проходить через директиву.
<select ng-model="education.degree.id" id="degreeList">
<option
value="{{degree.id}}"
ng-selected="{{education.degree == degree}}"
ng-repeat="degree in degrees">
{{degree.name}}
</option>
</select>
А в вашем контроллере (например)
.controller("myController", [
"$scope",
"$http",
function($scope, $http){
var self = {};
$scope.education = {
degree: {
id: -1,
name: ""
}
};
$scope.degrees =
[
{
id: 1,
name: 'High School'
},
{
id: 2,
name: 'Associates Degree'
},
{
id: 3,
name: 'Bachelor Degree'
},
{
id: 4,
name: 'Masters Degree'
},
{
id: 5,
name: 'M.B.A'
},
{
id: 6,
name: 'M.D'
},
{
id: 7,
name: 'Ph.D'
},
{
id: 8,
name: 'other'
}];
}]);
$scope.id
. Это самое простое решение, не зная точно, чего вы пытаетесь достичь.
Profile.getDegreeList() возвращает обещание, которое оценивается асинхронно. Вы регистрируете код, который выполняется, когда обещание будет разрешено. Внутри этого кода установлен идентификатор. Однако линия
console.log(id);
который сразу следует за созданием обещания, выполняется до того, как обетование будет разрешено.
Если вы хотите обработать идентификатор дальше или передать его другой функции, вы должны сделать это в рамках обещания. Это означает, что линия
ngModel.$parsers.push(...)
должен быть втянут в функцию, которая вызывается, когда обещание разрешено (т.е. функция, переданная then()
)
link
.