重用控制器中的角度事件

时间:2014-12-02 15:04:09

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-service

我在控制器中使用附加到作用域的以下事件:

  $scope.$on('$locationChangeStart', function( event ) {
      var answer = confirm('Are you sure?.')
      if (!answer) {
          event.preventDefault();
      }

如何使此事件逻辑可重用,以便我可以在多个控制器中使用它?是一种服务或工厂的方式去?是否更好地使用指令并将其作为元素,属性或类附加在相关视图中。我怀疑指令选项是对问题分离的轻微违反。

2 个答案:

答案 0 :(得分:1)

您可以在路线配置中创建参数。就我的例子而言,needConfirmation

$routeProvider
  .when('/route1', {
    templateUrl: 'page1.html',
    controller: 'Page1Ctrl'
  })
  .when('/route2', {
    templateUrl: 'page2.html',
    controller: 'Page2Ctrl',
    needConfirmation: true
  })
  .otherwise({
    redirectTo: '/route1'
  });

然后在run()阶段:

$rootScope.$on('$routeChangeStart', function (event, next) {
  if (next.needConfirmation) {
    if (!confirm('Are you sure?')) {
      event.preventDefault();
    }
  }
});

这是一个完整的例子:

angular.module('demo', ['ngRoute']);

angular.module('demo')
  .config(function ($routeProvider) {
  
    $routeProvider
      .when('/route1', {
        template: '<h1>this is the page 1</h1> <a href="#/route2">go to page 2</a>',
        controller: 'Page1Ctrl'
      })
      .when('/route2', {
        template: '<h1>this is the page 2</h1> <a href="#/route1">go to page 1</a>',
        controller: 'Page2Ctrl',
        needConfirmation: true
      })
      .otherwise({
        redirectTo: '/route1'
      });
  
  });

angular.module('demo')
  .run(function ($rootScope) {
    $rootScope.$on('$routeChangeStart', function (event, next) {
      if (next.needConfirmation) {
        if (!confirm('Are you sure?')) {
          event.preventDefault();
        }
      }
    });
  });

angular.module('demo')
  .controller('Page1Ctrl', function () {
  });

angular.module('demo')
  .controller('Page2Ctrl', function () {
  });
<script src="https://code.angularjs.org/1.3.5/angular.js"></script>
<script src="https://code.angularjs.org/1.3.5/angular-route.js"></script>

<div ng-app="demo">
  <div ng-view></div>  
</div>

答案 1 :(得分:0)

此事件是在更改网址之前广播的全局事件,您只需要定义handler一次。

  

如何使此事件逻辑可重用,以便我可以多次使用它   控制器?

这意味着不需要在多个控制器中定义。

使用module.run()。您可以使用$rootScope,这似乎适合您正在处理的此类事件。

当应用程序初始化时,

Module.run()在“每页”执行一次。如果您以后制作应用程序SPA,那么您仍然是金色的。

如果您关注TDD,请参阅以下关于创意的链接: -

Testing event chains and module.run() in Angular + Jasmine

  

为什么不在控制器中?

他们的工作应该是使模型可用于视图。

  

服务或工厂是否可行?

服务,工厂等应该只是帮助您的控制器,指令的对象。他们无权访问DOM范围。

  

使用指令并将其作为元素附加是否更好   相关视图中的属性或类。我怀疑这个指令   选择是对关注点分离的轻微违反。

指令是本地的。它们增强了HTML元素。 URL更改等事件是全局的。可以为浏览器的位置字段创建什么可能的指令?