2013-02-06 24 views
16

Chciałbym utworzyć niestandardowy typ wejścia podobny do sposobu, w jaki AngularJS implementuje "e-mail", na przykład.Jak utworzyć niestandardowy typ wejścia?

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

Co chciałbym stworzyć to input type tak:

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

Wszelkie pomysły, w jaki sposób można to osiągnąć? Do tej pory udało mi się tylko ustalić, w jaki sposób implementować dyrektywy niestandardowe, gdzie "ścieżka" jest nazwą znacznika, atrybutu lub klasy.

Na przykład mogę to uruchomić, ale jest to niespójne z innymi polami formularza i bardzo chciałbym, aby wyglądały tak samo.

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

Odpowiedz

19

Można tworzyć własne input type = „ścieżka” Tworząc dyrektywę wejściowy niestandardowej logiki, jeśli atrybut type jest ustawiony na „ścieżkę”.

Stworzyłem prosty przykład, który po prostu zastępuje \ z /. Dyrektywa ta wygląda następująco:

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

Aktualizacja: Zmieniono on, off do bind, unbind usunąć zależność jQuery. Przykład zaktualizowany.

+1

Stwarza to błąd dla type = „file”, ponieważ kątowe spodziewa ngmodel teraz – Pascalius

+1

@Pascalius można zmienić Wymagaj linii, aby: 'require: '? ngModel'' no uczynić ją opcjonalną. – Martin

+0

'off' i' on' są metodami jQuery. To nie zadziała, dopóki nie załadujesz również jQuery. –

2

Alternatywne rozwiązanie można uzyskać, korzystając z właściwości $parsers dla ngModelController. Ta właściwość reprezentuje łańcuch analizatorów składni, które są stosowane do wartości komponentu wejściowego przed przekazaniem ich do sprawdzania poprawności (i ostatecznie przypisaniem ich do modelu). Dzięki temu, rozwiązanie może być zapisany jako:

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, '/'); 
      }); 
     } 
    }; 
}); 

Należy pamiętać, że istnieje inna nieruchomość $formatters który to rurociąg z formatujących, które przekształcają wartość modelu do wartości wyświetlanej na wejściu.

Zobacz here dla plunkera.

0

Biorąc pod uwagę funkcję kompilacji jest pierwszy w kolejce, czy nie byłoby lepiej:

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); 
      }); 
     }); 
     } 
    } 
    }; 
}); 
Powiązane problemy