如何在 angularjs 中用 2 个相同的控制器制作原型?
How to make a prototype out of 2 identical controllers in angularjs?
在我的应用程序中,我有 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
现在 return 什么都没有了。
我已经阅读和观看了很多关于 AngularJS 服务、工厂、供应商的内容,但我不知道从这里该何去何从。 c2gcontroller.js
和 c2gbcontroller.js
原型的正确方法是什么?
伪继承怎么样
/* 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;
})
这就是结合使用 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>
在我的应用程序中,我有 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
现在 return 什么都没有了。
我已经阅读和观看了很多关于 AngularJS 服务、工厂、供应商的内容,但我不知道从这里该何去何从。 c2gcontroller.js
和 c2gbcontroller.js
原型的正确方法是什么?
/* 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;
})
这就是结合使用 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>