简体   繁体   English

为什么我的对象在Angular视图中没有更新?

[英]Why is my object not updated in the view in Angular?

I have SignalR working in my application: 我的SignalR正在我的应用程序中运行:

app.run(['SignalRService', function (SignalRService) {}]);

SignalRService: SignalRService:

app.service("SignalRService",  ['$rootScope', function ($rootScope) {
    var masterdataChangerHub = $.connection.progressHub;

    if (masterdataChangerHub != undefined) {
        masterdataChangerHub.client.updateProgress = function (progress) {
            $rootScope.$broadcast('progressChanged', progress);
        }

        masterdataChangerHub.client.completed = function (result) {
            $rootScope.$broadcast('taskCompleted', result);
        }
    }

    $.connection.hub.start();
}]);

As you can see I throw an event when a SignalR method gets invoked. 如您所见,当SignalR方法被调用时,我引发了一个事件。 This all works fine. 这一切都很好。 However, on 1 directive, my data won't get updated. 但是,在1条指令上,我的数据将不会更新。 Here's the code: 这是代码:

app.directive('certificateDetails', ['CertificateService', 'TradeDaysService', 'DateFactory', function (CertificateService, TradeDaysService, DateFactory) {
    return {
        restrict: 'E',
        templateUrl: '/Certificate/Details',
        scope: {
            certificateId: '=',
            visible: '=',
            certificate: '=',
            certificateSaved: '&'
        },
        link: function (scope, element, attributes) {
            scope.certificateFormVisible = false;
            scope.showCancelDialog = false;
            scope.splitCertificateFormVisible = false;
            scope.partialPayoutFormVisible = false;

            scope.$on("taskCompleted", function (evt, response) {
                console.log(response);

                    CertificateService.getCertificateById(scope.certificate.Id).then(function (response) {
                        scope.certificate = response;
                    });

            });

            scope.$watch('visible', function (newVal) {
                if (newVal === true) {
                    scope.showButtonBar = attributes.showButtonBar || true;

                    if (scope.certificateId) {
                        getCertificateById();
                    }
                }
            });

            function getCertificateById() {
                CertificateService.getCertificateById(scope.certificateId).then(function (response) {
                    scope.certificate = response;
                });
            };
        }
    }
}]);

The weird thing is, when I have my console open (I use Chrome) on the network tab, I can see that the directive makes a request to the right URL with the right parameters. 奇怪的是,当我在网络标签上打开控制台(使用Chrome)时,可以看到该指令使用正确的参数向正确的URL发出了请求。 Also, when the console is open, my data is updated in the view. 同样,当控制台打开时,我的数据也会在视图中更新。 However, and this is the strange part, when I close the console, nothing happens! 但是,这很奇怪,当我关闭控制台时,什么也没发生! It doesn't update the view.. 它不会更新视图。

I have also tried to put the code inside the taskCompleted event in a $timeout but that doesn't work either. 我也尝试将代码放入$timeouttaskCompleted事件中,但这也不起作用。

Could someone explain why this happens and how to solve this problem? 有人可以解释为什么会发生这种情况以及如何解决这个问题吗?

EDIT I 编辑我

This is how the getCertificateById looks like in my CertificateService 这就是getCertificateById在我的CertificateService中的样子

this.getCertificateById = function (id) {
    var promise = $http.post('/Certificate/GetById?id=' + id).then(function (response) {
        return response.data;
    });

    return promise;
};

Handling SignalR events will execute out of the Angular context. 处理SignalR事件将在Angular上下文之外执行。 You will need to $apply in order to force digest for these to work. 您需要$apply才能强制摘要使它们起作用。 I'd try to call $apply on $rootScope after the $broadcast : 我尝试在$broadcast之后在$rootScope上调用$apply

var masterdataChangerHub = $.connection.progressHub;

if (masterdataChangerHub != undefined) {
    masterdataChangerHub.client.updateProgress = function (progress) {
        $rootScope.$broadcast('progressChanged', progress);
        $rootScope.$apply();
    }

    masterdataChangerHub.client.completed = function (result) {
        $rootScope.$broadcast('taskCompleted', result);
        $rootScope.$apply();
    }
}

If this works then the issue definitely a binding issue between SignalR and Angular. 如果这可行,那么该问题肯定是SignalR和Angular之间的绑定问题。 Depending on what browser plugins you have installed, having the console open could trigger a digest for you. 根据所安装的浏览器插件的不同,打开控制台可能会触发摘要。

On the sample listeners for this project (that binds SignalR and Angular) , you can see that a $rootScope.$apply() is needed after handling on the client side: 此项目的示例侦听器(绑定SignalR和Angular)上 ,您可以看到在客户端处理后需要$rootScope.$apply()

//client side methods
listeners:{
    'lockEmployee': function (id) {
        var employee = find(id);
        employee.Locked = true;
        $rootScope.$apply();
    },
    'unlockEmployee': function (id) {
        var employee = find(id);
        employee.Locked = false;
        $rootScope.$apply();
    }
}

So, I'd assume that you would need to do the same. 因此,我认为您将需要执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM