Использование фильтра angularjs во входном элементе
Я надеюсь, что я не пропустил ничего очевидного в доке, если у меня есть, я уверен, что кто-то поможет.
Я использую asp.net webapi для возврата DTO, с полями даты. Они сериализуются с помощью JSON.Net (в формате '2013-03-11T12:37: 38.693').
Я хотел бы использовать фильтр, но в элементе ввода это возможно или я должен создать новый фильтр или директиву для этого?
// this just displays the text value
<input ui-datetime type="text" data-ng-model="entity.date" />
// this doesn't work at all
<input ui-datetime type="text" data-ng-model="{{entity.date|date:'dd/MM/yyyy HH:mm:ss a'}}" />
// this works fine
{{entity.date|date:'dd/MM/yyyy HH:mm:ss a'}}
есть ли ярлык, который я упускаю?
6 ответов:
короче говоря: если вы хотите, чтобы ваши данные имели другое представление в представлении и в модели, вам понадобится директива, который вы можете думать как двусторонний фильтр.
ваша директива будет выглядеть примерно так
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:
<input my-directive type="text" data-ng-model="entity.date" />
вот такой рабочий jsFiddle пример.
наличие разных значений в вашем поле ввода и в вашей модели противоречит самой природе ng-модели. Поэтому я предлагаю вам взять самый простой подход и применить свой фильтр внутри контроллера, используя отдельную переменную для форматированной даты и используя наблюдателей для синхронизации форматированных и оригинальных дат:
HTML:
<input ui-datetime type="text" data-ng-model="formattedDate" />
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'}; });
если ваш вход отображает только данные
Если вам действительно нужен вход просто дисплей некоторая информация и это какой-то другой элемент, который изменения угловая модель вы можете сделать более легкое изменение.
вместо того, чтобы писать новую директиву просто НЕ ИСПОЛЬЗОВАТЬ the
ng-model
и пользуйся добрым, старымvalue
.так вместо:
<input data-ng-model={{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" />
это:
<input value="{{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" />
и работает как шарм :)
полный пример, который форматирует числа, вставляя пробелы каждые 3 символа, начиная с конца:
'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, ' ').reverse() modelCtrl.$parsers.push (input) -> return unless input? input.replace(/\s/g, '')
использование:
<input ng-model="price" intersperse/>
Plunkr пример:http://plnkr.co/edit/qo0h9z
угловой имеет встроенный дата в формате функциональность, но чтобы применить ее к входу, где вы в конечном итоге хотите получить необработанную (неформатированную) дату, вам нужно создать пользовательский директива.
Пример Директивы:
(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; }); } }; }]); })();
затем применить его:
<input type="text" ng-model="$ctrl.DateField" utc-date />
вам не нужно будет создавать новый фильтр с нуля, так как angular уже имеет встроенный фильтр для типов дат. http://docs.angularjs.org/api/ng.filter:date
Я считаю, что это именно то, что вам нужно.