我想发布一个新的(对话)type
到 Angular ,所以我可以像使用 module.directive
一样使用它, module.filter
, module.controller
注册指令、过滤器和 Controller 。
我想注册我的 dialog
实例这样输入:
module.dialog('prompt',function(dependencies){
return {
templateUrl:'prompt.html',
controller:function($scope){},
something:'value'
}
});
我还希望能够在 Controller 中使用已注册的对话框(依赖注入(inject))
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
注册我的dialog
类型? dialogs
可注入(inject)到 controllers
ETC? 顺便提一句,
angular-ui
和 angular-strap
. dialog
作为一项服务,但作为一个单独的type
(此解决方案已在 angular-ui
中实现)。 最佳答案
这是一个非常有趣的问题。我会在我的答案前加上一个意见:我认为你不应该扩展 angular.module
提供dialog
方法。这些方法是内置 Angular 提供程序的快捷方式,Angular 团队会不时添加一些方法。由于您无需添加 dialog
即可访问您正在寻找的功能。方法,我不会。也就是说,下面的代码确实向您展示了一个非常基本的版本是如何工作的(它不会修改 Angular 模块原型(prototype),只是模块的单个实例)。
<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/
通过利用
$injector.invoke
在你的dialogProvider.register
功能,您可以提供使用像 controller
这样的键的能力在数据中你的configFn
返回。由于directive
已经有很多这样的工作了,您可能会从查看 the AngularJS source 中获益良多.
关于AngularJS - 使用自己的类型/提供者扩展模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16368066/