从 SignalR 回调更新 Angular 视图

Update Angular view from SignalR callback

有什么方法可以在 AngularJS 中创建模板,但在某些事件发生之前不能在 运行 中创建?

实际上我正在使用 SignalR。因此,当服务器调用客户端函数时,我希望根据服务器发送的数据显示一些 HTML。

假设我正在制作一个国际象棋游戏。 在服务器发送之前,我没有要显示在页面上的板。 在 HandleBar 中,我可以创建一个模板,当服务器以 [​​=39=] 格式发送板时,我可以编译模板并将其显示在页面上。

 gameHub.client.buildBoard = function(game){
        var template = Handlebars.compile($("board-template").html());
        $("board").html(template(game.Board))
    }

此 builBoard 函数被服务器调用。

在AngularJS我要创建一个Controller,但是$scope.board还没有加载let。

angular代码是

<div ng-app="game">
<div ng-controller="boardController">
    <div ng-repeat="row in board.Pieces">
        // Display Pieces
    </div>
</div>

JS

var app = angular.module("game", []);
app.controller("boardController", function ($scope) {
    $scope.size = 5;
    $scope.board= [];
});

这里棋盘被初始化为空数组。 现在服务器将使用所需的必要数据调用 buildBoard() 函数。

gameHub.client.buildBoard = function(board){
   // Code to take this board object and assign it to the $scope.board
}

从这里(在 controller 的范围之外),我如何更新 $scope.board 数组?

虽然我认为您应该多解释一下,并展示一些 angular 代码,但我认为您正在寻找 angular 没有的问题的解决方案。

考虑这段代码:

<div class="board-thing" ng-bind-html="board" ng-hide="board === null"></div>



...
.controller('myController', function($scope) {
  $scope.board = null;

  gameHub.client.buildBoard = function(game) {
    $scope.board = game.board;
  });
})

当数据加载时,$scope.board 被赋值给数据,视图立即通过作用域和 ng-bind-html 更新。无需任何编译!

您可以定义指令,以避免控制器与表示相关的代码混乱。

对于所有与业务相关的代码,在您的控制器之外定义服务。

在这种情况下,如果您想要推送数据,您需要定义一个事件调度程序 ("Server"),它会在发生远程更改时通知控制器。

这是一个示例控制器和相关模板。

angular
    .module('app')

    .controller("ChessController", function($scope, Server) {
        $scope.list = [0, 1, 2, 3, 4, 5, 6, 7];
        $scope.pieces = [];

        // "Server" is an angular service that abstracts your connection with your server
        // which can be based on socket.io, a raw websocket, HTTP polling...
        var chessGame = Server.getChessGame('xxx');

        chessGame.on('init', function(pieces) {
            // pieces == [
            //  {x: 0, y: 0, type: "pawn", color: "white"}
            //  {x: 0, y: 3, type: "king", color: "white"}
            //  {x: 2, y: 0, type: "queen", color: "white"}
            // ];

            $scope.pieces = pieces;
        });

        chessGame.on('remote_piece_moved', function(move) {
            // remove pieces at destination
            $scope.pieces = $scope.pieces.filter(function(p) { return p.x != move.dest_x && return p.y != move.dest_y; })
            // move piece.
            var piece = $scope.pieces.find(function(p) { return p.x == move.start_x && p.y == move.start_y; });
            piece.x = move.dest_x;
            piece.y = move.dest_y;
        });
    });


    .directive('chessPiece', function() {
        return {
            scope: false,
            link: function(scope, element) {
                scope.$watch('pieces', function(pieces) {
                    var piece = pieces.find(function(p) { return p.x == scope.col && p.y == scope.row; });

                    if (piece)
                        element.html('<img src="pieces/' + piece.type + '-' + piece.color + '.jpg"/>')
                    else
                        element.html('');
                }, true);
            }
        }
    });

模板

<table ng-controller="ChessController">
    <tr ng-repeat="row in list">
        <td ng-repeat="col in list" chess-piece></td>
    </tr>
</table>