javascript - Angular.js - 如何从 dom 事件绑定(bind)对象

标签 javascript angularjs angular-material

我正在开发一款游戏,它使用 angular.js 作为用户界面和游戏引擎类。

由于游戏引擎类和 Angular-Material 库之间存在冲突,我必须在 Angular 之后按顺序加载游戏引擎。

游戏引擎初始化后,它会分派(dispatch)一个自定义 dom 事件“clientReady”,并附有 2 个我需要在 Angular Controller 中访问的对象。

因此,在 app.run 上,我将这 2 个对象初始化到根范围,如下所示:

app.run(function($rootScope) {
    $rootScope.engine = {};
    $rootScope.editor = {};
    document.addEventListener('clientReady', function(e) {
        $rootScope.$apply(function() {
            $rootScope.engine = e.detail.engine;
            $rootScope.editor = e.detail.editor;
        });
    });
});

现在在我的 Controller 中,我尝试设置范围,例如:

$scope.player = $rootScope.engine.player;

这当然不起作用,因为“clientReady”事件发生在 Angular 初始化之后,并且当它开始运行 Controller 时根范围不存在。

有办法解决这个问题吗?我想知道我是否可以在 dom 事件之后以某种方式启动 Controller 。

问候 斯特凡

最佳答案

您无法“启动” Controller 。您可以转到 View ,它将运行 Controller 并将 Controller 的范围与其相应的 View 绑定(bind)。

因此,如果您希望始终监听此事件,则应该在 BodyController 中执行此操作。但是,如果您只想在某些 View 上监听此事件,那么您可能应该在app.run

上执行此操作

app.controller('BodyController', function($rootScope) {
  $document.addEventListener('clientReady', function(e) {
    
    //  Decide based on view when you want to change initialize the game or not
    if($location.path == '/login') {
      // don't let the user init as he/she is not logged in
    } else {
      //init
      // Store e in a service or $rootScope. I'd pick a service to do this as I wouldn't want to clutter my $rootScope
      GameService.save(e);
      // Handle transition to the new path
      $location.path('/something'); 
    }
    
    
    
  });  
})

或者,如果您只想在一个或多个 View 中收听此内容。 1. 在一个或多个 View 上监听 clientReady 事件(假设该事件仅初始化一次)

所以,假设您的主/默认 View 是“/”。然后在 HomeController 中执行以下操作:

app.controller('MainCtrl', function($scope, $document) {

    $document.addEventListener('clientReady', function(e) {
        // Store e in a service or $rootScope. I'd pick a service to do this as I wouldn't want to clutter my $rootScope
        GameService.save(e);
        // Goto to View/Controller that needs e
        $location.path('/something');
    });
}

  • 接下来,您可以在“/game”路径中开始所有游戏进程。这将起作用,因为仅当 clientReady 事件被触发时,isInitialized() 返回 true。如果 isInitialized()返回 false,那么 $location 将被更改并且 GameCtrl 的执行将停止(因为return`语句)
  • app.controller('GameCtrl', function($scope, GameService, $location) {
      if(!GameService.isInitialized()) {
        $location.path('/home'); // or to any other route you deem fit
        // Instead of redirecting, you can handle this gracefully on this view too. But I think that'll take much more effort.
        return; //Important so that the controller is not processed any further
      }
      // This is where the magic happens!
      $scope.engine = GameService.getEngine();
      $scope.editor = GameService.getEditor();
    }

  • 您的 GameService 是存储游戏引擎和其他客户端给定对象的位置。
  • angular.module('myApp').service('GameService', function() {
      // AngularJS will instantiate a singleton by calling "new" on this function
        this.getEngine = function() {
          // Logic  
        }
        this.getEditor = function () {
          // Logic  
        }
        this.isInitialized = function () {
          // Logic  
        }
    };

    关于javascript - Angular.js - 如何从 dom 事件绑定(bind)对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39334281/

    相关文章:

    javascript - 如何将 JavaScript Unicode 范围正则表达式转换为 PHP PCRE?

    jquery - 在页面调整大小的同一列中 Bootstrap 重新排序元素?

    javascript - 使用 Angular Material 步进器在输入类型文本中添加自定义验证

    javascript - 动态排列 md-dialog 标签

    java - 从 Angular 调用 Java EE Rest 服务

    angular - 升级到angular 12后,所有 Material 成分都是 "not a known element"

    javascript - 如何将 mysql 数据通过管道传输到浏览器窗口而不是 Nodejs 中的控制台?

    javascript - D3 : Spiral plot

    javascript - 引用错误: $ionicUser is not defined when use ionic-push

    angularjs - 在 Angular 2 (router v3.0.0-alpha.6) 中获取父路由参数