我想将一个新的(对话框)类型添加到angular,所以我可以使用它,就像我使用module.directive,module.filter,module.controller来注册指令,过滤器和控制器一样.
我想以这种方式注册我的对话框类型实例:
module.dialog('prompt',function(dependencies){ return { templateUrl:'prompt.html',controller:function($scope){},something:'value' } });
我还希望能够在控制器中使用已注册的对话框(依赖注入)
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(); }); } });
这归结为以下问题:
>如何扩展angular的模块以使module.dialog注册我的对话框类型?
>如何将注册的对话框注入控制器等?
顺便说一句,
>我知道angular-ui和angular-strap.
>我宁愿不使用对话框作为服务,而是作为一个单独的类型(此解决方案已经在angular-ui中实现).
这是一个非常有趣的问题.我将在答案前加上一个观点:我认为你不应该扩展angular.module来提供一个对话方法.这些方法是内置Angular提供程序的快捷方式,Angular团队不时添加一些方法.既然你可以在不添加对话方法的情况下访问你正在寻找的功能,我就不会.也就是说,下面的代码确实向您展示了它的基本版本如何工作(它不会修改Angular模块原型,只修改模块的单个实例).
<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',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/
通过利用dialogProvider.register函数中的$injector.invoke,您可以在configFn返回的数据中使用类似控制器的键.由于指令已经很像这样,你可以通过查看the AngularJS source获得很多.