Двусторонняя привязка данных после вызова Ajax
У меня проблема с двухсторонней привязкой данных AngularJS. Я постараюсь объяснить проблему как можно более четко: у меня есть список имен контактов. Для каждого элемента у меня есть кнопка Изменить. Когда я нажимаю на эту кнопку, я загружаю "полный" контакт из вызова Ajax, а затем я показываю окно с некоторыми полями ввода, связанными с только что полученным контактом ("телефон", "электронная почта" и т. Д.). Это интересная часть представления:
<div>
<div class="contact" data-ng-repeat="contact in contacts">
<span>{{contact.label}}</span>
<a href="" class="btn btn-xs btn-default" data-ng-click="openContactModal(contact.ID)">
Edit
</a>
</div>
</div>
Нажатие на кнопку "Редактировать" запускает эту функцию (присутствует в контроллере):
var newContact = null;
$scope.openContactModal = function(contactID){
newContact = new Contact(contactID);
newContact.onLoad().then(
function(){
//loading OK
$('#myModal').modal('show');
},
function(){
//loading Error
}
);
$scope.newContact = newContact;
};
Призыв к new Contact(contactID)
загружает контакт из базы данных с помощью вызова Ajax. Я открываю модальное окно в конце вызова Ajax (в ожидании обещания AngularJS). В модальном режиме все поля пусты, даже если они связаны с моделью контакта (newContact.phone
, newContact.email
так далее.). Я уже проверил, что Ajax-вызов работает нормально (печатая полученный JSON). Я полагаю, что мне что-то не хватает в проблеме двустороннего связывания данных. Странный факт, что, если я попытаюсь заполнить пустые модальные поля, newContact
Модель хорошо реагирует, как будто двусторонняя привязка данных работает хорошо с точки зрения модели, но не наоборот. Заранее спасибо!
РЕДАКТИРОВАТЬ: это служба, которая получает контакт:
angular.module("app").factory("Contact", ["ContactDBServices", "$q",
function(ContactDBServices, $q){
return function(contactID){
//the contact itself
var self = this;
var contactPromise = $q.defer();
//attributi del contatto
this.firstName = null;
this.ID = null;
this.lastName = null;
this.phone = null;
this.fax = null;
this.mobile = null;
this.email = null;
this.web = null;
//the Ajax call
var metacontact = ContactDBServices.find({ID:contactID},
function(){
this.ID = contactID;
this.firstName = metacontact.contact_name;
this.lastName = metacontact.contact_last_name;
this.phone = metacontact.contact_phone;
this.fax = metacontact.contact_fax;
this.mobile = metacontact.contact_mobile;
this.email = metacontact.contact_email;
this.web = metacontact.contact_web;
//!!!THE FOLLOWING PRINTS ARE GOOD!!!!
console.log(this.ID);
console.log(this.firstName);
console.log(this.lastName);
console.log(this.phone);
console.log(this.fax);
contactPromise.resolve("OK");
},
function(){
contactPromise.reject("Error");
}
);
this.onLoad = function(){
return contactPromise.promise;
};
}
}]);
Если я печатаю те же значения в контроллере, все эти значения undefined
:
var newContact = null;
$scope.openContactModal = function(contactID){
newContact = new Contact(contactID);
newContact.onLoad().then(
function(){
//!!!!!!!!THE FOLLOWING PRINTS ARE ALL UNDEFINED!!!!
console.log(newContact.firstName);
console.log(newContact.lastName);
console.log(newContact.phone);
console.log(newContact.fax);
$('#myModal').modal('show');
},
function(){
//loading Error
}
);
$scope.newContact = newContact;
};
Это странно. Кажется, что-то вроде проблемы с синхронизацией:-/, чтобы быть точным, вот пример модальной части:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h2>Contact</h2>
</div>
<div class="modal-body">
<label>
Name
<input class="form-control" id="new_contact_name" data-ng-model="newContact.firstName" placeholder="Name">
</label>
<!-- ...and so on -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" data-ng-click="createContact()">Crea</button>
</div>
</div>
</div>
1 ответ
В конце концов я нашел ошибку. Это была моя ошибка, и она принадлежит не AngularJS, а Javascript: вы заметите, что в службе контактов я сделал:
//the Ajax call
var metacontact = ContactDBServices.find({ID:contactID},
function(){
this.ID = contactID;
this.firstName = metacontact.contact_name;
this.lastName = metacontact.contact_last_name;
this.phone = metacontact.contact_phone;
this.fax = metacontact.contact_fax;
this.mobile = metacontact.contact_mobile;
this.email = metacontact.contact_email;
this.web = metacontact.contact_web;
},
function(){
contactPromise.reject("Error");
}
);
ясно пишу this.
в функции обратного вызова я не влиял на значения Контакта, но на атрибуты функции! Чтобы решить эту проблему, мне пришлось изменить обратный вызов следующим образом:
//the Ajax call
var metacontact = ContactDBServices.find({ID:contactID},
function(){
self.ID = contactID;
self.firstName = metacontact.contact_name;
self.lastName = metacontact.contact_last_name;
self.phone = metacontact.contact_phone;
self.fax = metacontact.contact_fax;
self.mobile = metacontact.contact_mobile;
self.email = metacontact.contact_email;
self.web = metacontact.contact_web;
},
function(){
contactPromise.reject("Error");
}
);
где
var self = this;
вне обратного вызова.