2013-02-06 18 views
16

Vorrei creare un tipo di input personalizzato simile al modo in cui AngularJS implementa "email", ad esempio.Come creare un tipo di input personalizzato?

<input type="email" ng-model="user.email" /> 

Quello che vorrei per creare è un tipo di ingresso in questo modo:

<input type="path" ng-model="page.path" /> 

Delle idee su come questo può essere realizzato? Finora, sono stato in grado di capire come implementare le direttive personalizzate dove 'percorso' è il nome del tag, attributo o classe.

Ad esempio, posso farlo funzionare ma è incoerente con gli altri campi modulo e mi piacerebbe davvero che fossero uguali.

<input type="text" ng-model="page.path" path /> 
app.directive('path', function() { 
    return { 
    require: 'ngModel', 
    link: function(scope, elm, attrs, ctrl) { ... } 
    }; 
}); 

risposta

19

È possibile creare il proprio input type = "percorso" con la creazione di una direttiva di ingresso con logica personalizzata se l'attributo type è impostato su "percorso".

Ho creato un semplice esempio che sostituisce semplicemente \ con /. La direttiva si presenta così:

module.directive('input', function() { 
    return { 
     restrict: 'E', 
     require: 'ngModel', 
     link: function (scope, element, attr, ngModel) { 
      if (attr.type !== 'path') return; 

      // Override the input event and add custom 'path' logic 
      element.unbind('input'); 
      element.bind('input', function() { 
      var path = this.value.replace(/\\/g, '/'); 

      scope.$apply(function() { 
       ngModel.$setViewValue(path); 
      }); 
      }); 
     } 
    }; 
}); 

Example

Aggiornamento: Cambiato on, off-bind, unbind per rimuovere jQuery dipendenza. Esempio aggiornato.

+1

Questo crea un errore per type = "file", perché angolare si aspetta ngmodel ora – Pascalius

+1

@Pascalius è possibile modificare la richiede la linea per: 'richiede: '? ngModel'' no lo rende opzionale. – Martin

+0

'off' e' on' sono metodi jQuery. Questo non funzionerà se non hai caricato jQuery. –

2

Una soluzione alternativa può essere ottenuta utilizzando la proprietà $parsers di ngModelController. Questa proprietà rappresenta una catena di parser che vengono applicati al valore del componente di input prima di passarli alla convalida (e alla fine assegnarli al modello). Con questo, la soluzione può essere scritta come:

module.directive('input', function() { 
    return { 
     restrict: 'E', 
     require: 'ngModel', 
     link: function (scope, element, attr, ngModel) { 
      if (attr.type !== 'path') return; 

      ngModel.$parsers.push(function(v) { 
      return v.replace(/\\/g, '/'); 
      }); 
     } 
    }; 
}); 

Nota che c'è un'altra proprietà $formatters che è una pipeline di formattatori che trasformano un valore del modello nel valore visualizzato nel ingresso.

Vedere here per il plunker.

0

Considerando la funzione di compilazione è il primo della fila, non sarebbe meglio con:

module.directive('input', function() { 
    return { 
    restrict: 'E', 
    require: 'ngModel', 
    compile: function Compile(tElement, tAttrs) { 
     if (tAttrs.type !== 'path') return; 

     return function PostLink(scope, element, attr, ngModel) { 
     // Override the input event and add custom 'path' logic 
     element.unbind('input'); 
     element.bind('input', function() { 
      var path = this.value.replace(/\\/g, '/'); 

      scope.$apply(function() { 
      ngModel.$setViewValue(path); 
      }); 
     }); 
     } 
    } 
    }; 
}); 
Problemi correlati