【问题标题】:How to make a prototype out of 2 identical controllers in angularjs?如何在 angularjs 中用 2 个相同的控制器制作原型?
【发布时间】:2015-04-13 23:00:45
【问题描述】:

在我的应用程序中,我有 2 个几乎相同的控制器。很多功能都是一样的,所以我想制作它们的原型。这是控制器 #1:

c2gcontroller.js

angular.module('c2gyoApp')
  .controller('C2gCtrl', function($scope) {
    // some unique stuff
    $scope.feeDay = 59;
    ...
    // the identical functions
    $scope.getMinutes = function(minutes) {
      var duration = moment.duration(minutes, 'm');
      return duration.minutes();
    };
    ...
  });

和控制器 #2:

c2gbcontroller.js

angular.module('c2gyoApp')
  .controller('C2gbCtrl', function($scope) {
    // some unique stuff
    $scope.feeDay = 89;
    ...
    // the identical functions
    $scope.getMinutes = function(minutes) {
      var duration = moment.duration(minutes, 'm');
      return duration.minutes();
    };
    ...
  });

我尝试将$scope.getMinutes 放入工厂:

smfactory.js

angular.module('c2gyoApp')
  .factory('smfactory', function() {
    return {
      getHours: function(minutes) {
        var duration = moment.duration(minutes, 'm');
        return Math.ceil(duration.asHours() % 24);
      }
    };
  });

我已将 smfactory 注入 c2gcontroller.js

c2gcontroller.js(尝试 #1)

angular.module('c2gyoApp')
  .controller('C2gCtrl', function($scope, smfactory) {
    ...
    // the identical functions
    $scope.getHours = smfactory.getHours(minutes);
    ...
  });

这会产生分钟未定义的错误

 line 33  col 42  'minutes' is not defined.

所以我尝试了:

c2gcontroller.js(尝试 #2)

angular.module('c2gyoApp')
  .controller('C2gCtrl', function($scope, smfactory) {
    ...
    // the identical functions
    $scope.getMinutes = function(minutes) {
      return smfactory.getHours(minutes);
    };
    ...
  });

这不会产生错误,但我的应用确实变得无响应。基本上$scope.getMinutes 现在什么都不返回了。

我已经阅读并观看了很多关于 AngularJS 服务、工厂、提供者的信息,但我不知道从这里可以去哪里。原型c2gcontroller.jsc2gbcontroller.js 的正确方法是什么?

【问题讨论】:

    标签: angularjs dependency-injection angularjs-service angularjs-factory angularjs-provider


    【解决方案1】:

    这就是结合使用 JavaScript 的绝妙之处,controller as 语法真的派上用场了。

    如果我们将您的常用功能提取到一个普通的旧对象中:

    var commonStuff = {
       getHours: function(minutes) {
            var duration = moment.duration(minutes, 'm');
            return Math.ceil(duration.asHours() % 24);
       }
    };
    

    然后,如果我们将控制器重构为普通的 JS 对象,我们可以使用两种方法之一的 mixin 来扩充它。要么直接到对象本身,要么通过原型。

    //Using the instance
    function MyCtrl(){
       var vm = this;
    
       angular.extend(vm, commonStuff);
    
       //Other stuff
    }
    
    //Or via the prototype
    function MyCtrl(){
       var vm = this;
    }
    
    //Controller specific
    MyCtrl.prototype = {
    
    };
    
    angular.extend(MyCtrl.prototype, commonStuff);
    

    最大的不同是现在您可以直接通过使用controller as 语法来引用控制器。

    <div ng-controller="myCtrl as ctrl">
      <a href="" ng-click="ctrl.getHours(120)">Get Hours</a>
    </div>
    

    【讨论】:

    • 非常感谢您的深刻回答!我决定使用 user2264997 答案,因为它不会破坏 Yeoman 命名方案。
    【解决方案2】:

    angular.extend 的伪继承怎么样

    /* define a "base" controller with shared functionality */
    .controller('baseCtrl', ['$scope', .. 
        function($scope, ...) {
    
      $scope.getMinutes = function(minutes) {
        var duration = moment.duration(minutes, 'm');
        return duration.minutes();
      };
    
    
    .controller('C2gCtrl', ['$controller', '$scope', ...
        function($controller, $scope, ...) {
    
      // copies the functionality from baseCtrl to this controller
      angular.extend(this, $controller('baseCtrl', {$scope: $scope}));
    
      // some unique stuff
      $scope.feeDay = 59;
    
    })
    
    .controller('C2gbCtrl', ['$controller', '$scope', ...
        function($controller, $scope, ...) {
    
      // copies the functionality from baseCtrl to this controller
      angular.extend(this, $controller('baseCtrl', {$scope: $scope}))
    
      // some unique stuff
      $scope.feeDay = 89;
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 2012-02-05
      • 2014-04-19
      相关资源
      最近更新 更多