如何根据信号器请求的结果设置控制器范围?

时间:2016-02-06 01:43:40

标签: javascript angularjs model-view-controller signalr

我创建了一个简单的信号器集线器,它在一个名为hubService的angularjs服务中启动。我能够成功地将hubService注入我的控制器。但是,当我调用hub方法时,它会正确返回一些数据。我无法通过signalr方法回调在控制器中设置$ scope。

/// <reference path="../typings/angularjs/angular.d.ts" />
// The application.
var app = angular.module("app", []);

app.service("hubService", function () {
    this.notification = $.connection.notificationHub;
    $.connection.hub.start();
});

// A controller manages some part of the application.
app.controller("MyController", function ($scope,hubService) {
    $scope.message = "";
    $scope.messageOutput = "";

    hubService.notification.client.addNewMessageToPage = function(message) {
        this.messageOutput = message; // this fails.
    }

    $scope.doSomething = function () {
        hubService.notification.server.send($scope.message);
    }
});

UI代码也很简单,如下所示:

    <div ng-controller="MyController">
        <input type="text" ng-model="message" />
        <button ng-click="doSomething()">Do Something</button>
        {{ messageOutput }}
    </div>

从信号器回调中正确更新范围的最佳方法是什么?

如果我更改为signalr回调的以下代码,我可以得到一些结果。

    hubService.notification.client.addNewMessageToPage = function(message) {
        this.messageOutput = message; // this works but
        this.$apply();                // if I don't have this it is still broken.
    }.bind($scope);
    ...

这不太理想,因为它看起来有点像黑客。

1 个答案:

答案 0 :(得分:0)

使用$apply()不是黑客攻击。

当从角度上下文之外的事件或代码更新范围时,有必要告诉它有关它的角度,以便运行摘要来更新视图。

最好使用$timeout(内部调用$apply()),以免遇到摘要已在进行中的冲突。这会将调用推送到任何活动摘要周期的结束