5

在我的应用程序中,我有 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);
      }
    };
  });

我已经注入smfactoryc2gcontroller.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.js原型和的正确方法是c2gbcontroller.js什么?

4

2 回答 2

3

这是结合使用 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>
于 2015-02-13T00:43:01.007 回答
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;
})
于 2015-02-13T00:42:17.577 回答