AngularJS - 扩大与自己的类型/供应商模块 [英] AngularJS - extending module with own types / providers
问题描述
我想广告一个新的(对话)键入
来的角,所以我可以使用它,就像我使用 module.directive
, module.filter
, module.controller
注册指令,过滤器和控制器。
I want to ad a new (dialog) type
to angular, so I could use it just like I use module.directive
, module.filter
, module.controller
to register directives, filters and controllers.
我要注册我的对话框
键入这样的实例:
I want to register my instances of dialog
type this way:
module.dialog('prompt',function(dependencies){
return {
templateUrl:'prompt.html',
controller:function($scope){},
something:'value'
}
});
我也希望能够在控制器使用注册对话框(依赖注入)
I also want to be able to use registered dialogs in controllers (dependency injection)
module.controller('ListCtrl',function($scope,prompt){
$scope.deleteItem = function(item){
prompt('Do you want to delete this item?').then(function(result){
if(result) item.$delete();
});
}
});
这可以归结为以下几个问题:
-
我如何延长角的模块有
module.dialog
注册我的对话框
类型?
如何让我的注册对话框
注射到控制器
等
How do I make my registered dialogs
injectable in to controllers
etc?
顺便说一句,
- 的我知道
角UI
和角带
的李> - 的我宁可不使用
对话框
作为一种服务,而是作为一个独立键入
(这个解决方案已经在角UI
)。的 实施
- I know about
angular-ui
andangular-strap
. - I would rather not use
dialog
as a service, but as a separatetype
(this solution is already implemented inangular-ui
).
推荐答案
这是一个pretty有趣的问题。我会preFIX我的回答有自己的见解:我不认为你应该延长 angular.module
提供了对话框
方法。这些方法是捷径到内置角供应商,和角队增加了一些不时。既然你可以访问该功能,你正在寻找的没有的添加对话框
方法,我不会。这就是说,code以下不会告诉你如何这是一个非常基本的版本可能工作(它不会修改角模块原型,只是模块的单个实例)。
This is a pretty interesting question. I'll prefix my answer with an opinion: I don't think you should extend angular.module
to provide a dialog
method. Those methods are shortcuts into built-in Angular providers, and the Angular team adds some from time to time. Since you can get access to the functionality you're looking for without adding the dialog
method, I wouldn't. That said, the code below does show you how a very basic version of this might work (it doesn't modify the Angular module prototype, just the single instance of the module).
<div ng-app="myApp">
<div ng-controller='MainController'>
<div>
<button ng-click='askName()'>Ask Name</button>
<button ng-click='askNameAgain()'>Ask Name Again</button>
<button ng-click='askAge()'>Ask Age</button>
<button ng-click='askFood()'>Ask Food</button>
</div>
<div>{{lastResponse}}</div>
</div>
</div>
var app = angular.module('myApp', []);
// Provide some basic injectables for testing
app.constant('nameString', 'NAME');
app.constant('ageString', 'AGE');
app.constant('foodString', 'FAVORITE FOOD');
// Create the dialog provider
app.provider('dialog', function($provide, $injector) {
var dialogs = {};
this.register = function(name, configFn) {
// Create a new service
$provide.factory(name, function($window, $q) {
dialogs[name] = function() {
// Get data based on DI injected version of configFn
var data = $injector.invoke(configFn);
// faking async here since prompt is really synchronous
var deferred = $q.defer();
var response = $window.prompt(data.text);
deferred.resolve(response);
return deferred.promise;
};
return dialogs[name];
});
};
// Injecting the service itself gives you a function that
// allows you to access a dialog by name, much like $filter
this.$get = function() {
return function(name) {
return dialogs[name];
};
};
});
// Providing dialog injectables via app.config
app.config(function(dialogProvider) {
dialogProvider.register('askFood', function(foodString) {
return { text: 'What is your ' + foodString + '?' }
});
});
// Alternatively, shortcut to accessing the dialogProvider via app.dialog
app.dialog = function(name, configFn) {
app.config(function(dialogProvider) {
dialogProvider.register(name, configFn);
});
};
app.dialog('askName', function(nameString) {
return { text: 'What is your ' + nameString + '?' }
});
app.dialog('askAge', function(ageString) {
return { text: 'What is your ' + ageString + '?' }
});
app.controller('MainController',
function($scope, askName, askAge, askFood, dialog) {
var setLastResponse = function(result) {
$scope.lastResponse = result;
};
$scope.askName = function() {
askName().then(setLastResponse);
};
$scope.askNameAgain = function() {
// get the dialog through the dialog service
// much like how $filter works
var theDialog = dialog('askName');
theDialog().then(setLastResponse);
};
$scope.askAge = function() {
askAge().then(setLastResponse);
};
$scope.askFood = function() {
askFood().then(setLastResponse);
};
});
下面是一个工作的例子: http://jsfiddle.net/BinaryMuse/zj4Jq/
Here is a working example: http://jsfiddle.net/BinaryMuse/zj4Jq/
借助 $ injector.invoke
你的 dialogProvider.register
函数中,您可以提供能够使用在数据如控制器
的一个关键你的 configFn
的回报。由于指令
作品很多像这样已经,你可能会获得从检查出了很多<一个href=\"https://github.com/angular/angular.js/blob/af0eaa304748f330739a4b0aadb13201126c5407/src/ng/compile.js#L177\"相对=nofollow>的AngularJS源。
By leveraging $injector.invoke
inside of your dialogProvider.register
function, you can provide the ability to use a key like controller
in the data your configFn
returns. Since directive
works a lot like this already, you may gain a lot from checking out the AngularJS source.
这篇关于AngularJS - 扩大与自己的类型/供应商模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!