Javascript Ajax调用后的双向数据绑定

Javascript Ajax调用后的双向数据绑定,javascript,jquery,ajax,angularjs,2-way-object-databinding,Javascript,Jquery,Ajax,Angularjs,2 Way Object Databinding,我对AngularJS双向数据绑定有问题。我会尽可能清楚地解释这个问题:我有一个联系人名单。对于每个元素,我都有一个编辑按钮。当我点击该按钮时,我从一个Ajax呼叫中加载“点击”的完整联系人,然后显示一个窗口,其中包含一些链接到刚刚检索到的联系人的输入字段(“电话”、“电子邮件”等)。这是视图中有趣的部分: <div> <div class="contact" data-ng-repeat="contact in contacts"> &l

我对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>
调用
newcontact(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;
            };

    }
}]);  
但是,如果我在控制器中打印相同的值,则所有这些值都是未定义的:

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>

接触
名称
接近
克雷亚

最终我发现了错误。这是我的一个错误,它不属于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");
    }
);
显然,在回调函数中写入
这个。
不会影响联系人值,但会影响函数属性!要解决此问题,我必须以以下方式更改回调:

//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");
    }
);
在哪里


回调之外。

是否
newContact.onLoad()
正确?是的,它是一个返回角度承诺的函数。模式在Ajax调用结束时正确显示,检索到的Json包含正确的值,但这些值与视图没有“双向数据绑定”。您的模式是如何连接的?它的控制器是否共享您正在填充的
newContact
对象
$scope
?包含模式的html页面有一个名为“customerController”的唯一控制器。模态与整个页面共享$scope。我刚刚编辑了我的问题,也许现在更完整了。谢谢你的帮助。
//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;