Usando o filtro angularjs no elemento de input

Espero não ter perdido nada óbvio no doco, se tenho certeza que alguém vai ajudar.

Estou usando o asp.net webapi para retornar um DTO, com campos de data. Estes são serializados usando JSON.Net (no formato ‘2013-03-11T12: 37: 38.693’).

Eu gostaria de usar um filtro, mas em um elemento INPUT, isso é possível ou devo criar um novo filtro ou diretiva para conseguir isso?

// this just displays the text value  // this doesn't work at all  // this works fine {{entity.date|date:'dd/MM/yyyy HH:mm:ss a'}} 

Existe algum atalho que estou faltando?

Resumindo: se você quiser que seus dados tenham uma representação diferente na visualização e no modelo, você precisará de uma diretiva , que pode ser considerada um filtro bidirecional .

Sua diretiva seria algo como

 angular.module('myApp').directive('myDirective', function() { return { require: 'ngModel', link: function(scope, element, attrs, ngModelController) { ngModelController.$parsers.push(function(data) { //convert data from view format to model format return data; //converted }); ngModelController.$formatters.push(function(data) { //convert data from model format to view format return data; //converted }); } } }); 

HTML:

  

Aqui está um exemplo de jsFiddle .

Ter valores diferentes em seu campo de input e em seu modelo vai contra a própria natureza do modelo ng. Portanto, sugiro que você adote a abordagem mais simples e aplique seu filtro dentro do controlador, usando uma variável separada para a data formatada, e empregando observadores para manter as datas formatadas e originais em sincronia:

HTML:

  

JS:

 app.controller('AppController', function($scope, $filter){ $scope.$watch('entity.date', function(unformattedDate){ $scope.formattedDate = $filter('date')(unformattedDate, 'dd/MM/yyyy HH:mm:ss a'); }); $scope.$watch('formattedDate', function(formattedDate){ $scope.entity.date = $filter('date')(formattedDate, 'yyy/MM/dd'); }); $scope.entity = {date: '2012/12/28'}; }); 

Se sua input exibir apenas dados

Se você realmente precisa de uma input para simplesmente exibir alguma informação e é algum outro elemento que muda o modelo angular, você pode fazer uma mudança mais fácil.

Em vez de escrever uma nova diretiva, simplesmente NÃO USE o ng-model e use um value bom e antigo.

Então, ao invés de:

  

Isso fará:

  

E funciona como um encanto 🙂

Exemplo completo que formata números, inserindo espaços a cada 3 caracteres, começando do final:

 'use strict' String::reverse = -> @split('').reverse().join('') app = angular.module('app', []) app.directive 'intersperse', -> require: 'ngModel' link: (scope, element, attrs, modelCtrl) -> modelCtrl.$formatters.push (input) -> return unless input? input = input.toString() input.reverse().replace(/(.{3})/g, '$1 ').reverse() modelCtrl.$parsers.push (input) -> return unless input? input.replace(/\s/g, '') 

Uso:

  

Exemplo Plunkr: http://plnkr.co/edit/qo0h9z

Angular construiu em funcionalidade de formato de data , mas para aplicá-lo a uma input onde você eventualmente gostaria de obter a data bruta (não formatada), você precisa criar uma diretiva personalizada.

Exemplo de Diretiva:

 (function () { 'use strict'; angular.module('myApp').directive('utcDate', ['$filter', function ($filter) { return { restrict: 'A', //restricting to (A)ttributes require: 'ngModel', link: function (scope, elem, attrs, model) { if (!model) return; var format = 'MM/dd/yyyy h:mm:ss a'; var timezone = 'UTC'; //format the date for display model.$formatters.push(function (value) { //using built-in date filter return $filter('date')(value, format, timezone); }); //remove formatting to get raw date value model.$parsers.push(function (value) { var date = Date.parse(value); return !isNaN(date) ? new Date(date) : undefined; }); } }; }]); })(); 

Então, para aplicá-lo:

  

Você não precisaria criar um novo filtro a partir do zero, já que o angular já possui um filtro interno para os tipos de data. http://docs.angularjs.org/api/ng.filter:date

Eu acredito que é exatamente o que você precisa.