2013-05-03 19 views
8

voglio annuncio di un nuovo (finestra di dialogo) type ad angolare che si estende, così ho potuto usarla proprio come io uso module.directive, module.filter, module.controller registrare direttive, filtri e regolatori.AngularJS - modulo con tipi propri fornitori/

Vorrei iscrivermi mie istanze di dialog tipo in questo modo:

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

Voglio anche essere in grado di utilizzare le finestre di dialogo registrati nel controller (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(); 
     }); 
    } 
}); 

questo si riduce alle seguenti domande:

  1. Come estendere il modulo di angular per fare in modo che module.dialog registri i miei tipi dialog?

  2. Come si effettua la registrazione del dialogs immesso in controllers ecc.?

Btw,

  • che so di angular-ui e angular-strap.
  • Preferisco non utilizzare dialog come servizio, ma come separato type (questa soluzione è già implementata in angular-ui).
+0

perché non dovresti semplicemente usare le direttive? – charlietfl

+0

C'è una ragione per cui si vorrebbe farlo in contrasto con la soluzione di bootstrap? – zcaudate

+0

@zcaudate, non mi piace il modo in cui il bootstrap registra i dialoghi: si definisce la finestra di dialogo nel controller. Volevo separare i dialoghi dai controller. – g00fy

risposta

7

Questa è una domanda piuttosto interessante. Prefisso la mia risposta con un parere: non penso che dovresti estendere lo angular.module per fornire un metodo dialog. Questi metodi sono scorciatoie nei provider Angular incorporati e il team Angular ne aggiunge alcuni di volta in volta. Dal momento che puoi accedere alla funzionalità che stai cercando senza aggiungendo il metodo dialog, non lo farei. Detto questo, il codice qui sotto mostra come una versione di base di questo potrebbe funzionare (non modifica il prototipo del modulo Angolare, solo la singola istanza del modulo).

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

Ecco un esempio di lavoro: http://jsfiddle.net/BinaryMuse/zj4Jq/

Sfruttando $injector.invoke all'interno della vostra funzione dialogProvider.register, è possibile fornire la possibilità di utilizzare una chiave, come controller nei dati vostri configFn restituisce. Dal directive funziona già così, potresti guadagnare molto dal check-out the AngularJS source.

Problemi correlati