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

时间:2015-01-09 08:41:43

标签: javascript angularjs angularjs-directive

我的SignalR工作在我的应用程序中:

app.run(['SignalRService', function (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();
}]);

正如您所看到的,我在调用SignalR方法时抛出一个事件。一切正常。但是,在1指令上,我的数据不会得到更新。这是代码:

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;
                });
            };
        }
    }
}]);

奇怪的是,当我在网络选项卡上打开控制台(我使用Chrome)时,我可以看到该指令使用正确的参数向正确的URL发出请求。此外,当控制台打开时,我的数据会在视图中更新。然而,这是一个奇怪的部分,当我关闭控制台时,没有任何反应!它没有更新视图..

我还试图将taskCompleted事件中的代码放在$timeout中,但这也不起作用。

有人可以解释为什么会发生这种情况以及如何解决这个问题吗?

编辑我

这是我的CertificateService

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

    return promise;
};

1 个答案:

答案 0 :(得分:2)

处理SignalR事件将在Angular上下文中执行。您需要$apply才能强制使用摘要来实现这些功能。我试图在$apply之后$rootScope上致电$broadcast

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();
    }
}

如果这样可行,那么这个问题肯定是SignalR和Angular之间的一个约束问题。根据您安装的浏览器插件,打开控制台可能会触发摘要。

this project (that binds SignalR and 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();
    }
}

所以,我假设您需要这样做。