2013-05-03 3 views
8

ich einen neuer (Dialog) type zu kantig Anzeige geschaltet werden soll, so könnte ich es verwenden, so wie ich module.directive verwenden, module.filter, module.controller Richtlinien, Filter und Regler zu registrieren.AngularJS - Verlängerung Modul mit eigenen Typen/Anbieter

Ich möchte meine Instanzen dialog Typ registrieren diese Weise:

module.dialog('prompt',function(dependencies){ 
    return { 
     templateUrl:'prompt.html', 
     controller:function($scope){}, 
     something:'value' 
    } 
}); 

Ich möchte auch in der Lage sein, in Controller registrierten Dialoge zu verwenden (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(); 
     }); 
    } 
}); 

Dies läuft darauf hinaus, zu folgenden Fragen:

  1. Wie erweitere ich das Winkelmodul so, dass module.dialog meine dialog Typen registriert?

  2. Wie kann ich meine registrierte dialogs injizierbare in controllers etc?

Btw,

  • Ich weiß über angular-ui und angular-strap.
  • Ich würde lieber nicht dialog als Service verwenden, sondern als separate type (diese Lösung ist bereits in angular-ui implementiert).
+0

Warum würden Sie nicht einfach Anweisungen verwenden? – charlietfl

+0

Gibt es einen Grund, warum Sie dies im Gegensatz zur Bootstrap-Lösung tun sollten? – zcaudate

+0

@zcaudate, ich mag nicht wie Bootstrap Dialoge registriert - definieren Sie Ihren Dialog in der Steuerung. Ich wollte Dialoge von den Controllern trennen. – g00fy

Antwort

7

Das ist eine ziemlich interessante Frage. Ich werde meiner Antwort eine Meinung voranstellen: Ich denke nicht, dass Sie angular.module erweitern sollten, um eine dialog Methode zur Verfügung zu stellen. Diese Methoden sind Abkürzungen zu integrierten Angular-Anbietern, und das Angular-Team fügt von Zeit zu Zeit einige hinzu. Da Sie Zugriff auf die Funktionalität erhalten können, die Sie suchen ohne Hinzufügen der dialog Methode, würde ich nicht. Der folgende Code zeigt Ihnen jedoch, wie eine sehr grundlegende Version davon funktionieren könnte (es ändert nicht den Prototyp des Angular-Moduls, sondern nur die einzelne Instanz des Moduls).

<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); 
    }; 
}); 

Hier ist ein funktionierendes Beispiel: http://jsfiddle.net/BinaryMuse/zj4Jq/

von $injector.invoke innerhalb Ihrer dialogProvider.register Funktion nutzen, können Sie bieten die Möglichkeit, einen Schlüssel wie controller in den Daten Ihrer configFn kehrt zu verwenden. Da directive bereits so funktioniert, können Sie beim Auschecken sehr viel gewinnen the AngularJS source.