从SignalR回调更新角度视图

时间:2015-08-14 14:12:12

标签: angularjs signalr handlebars.js

有没有什么方法可以在AngularJS中创建模板但是在某个事件之前不能运行它?

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

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

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

此buildingBoard函数由服务器调用。

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

角度代码是

<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
}

从这里(在控制器范围之外),如何更新$ scope.board数组?

2 个答案:

答案 0 :(得分:1)

虽然我相信你应该多解释一下自己,并展示一些角度代码,但我认为你正在寻找角度不具备问题的解决方案。

考虑以下代码:

<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立即更新视图。不需要任何编译!

答案 1 :(得分:0)

您可以定义指令,以避免使用与演示文稿相关的代码使控制器混乱。

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

在这种情况下,您需要推送数据,您需要定义一个事件调度程序(“服务器”),它将在发生远程更改时通知控制器。

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

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>