Использование углового фильтра в входном элементе
Надеюсь, что я не пропустил ничего очевидного в doco, если у меня есть, я уверен, что кто-то поможет.
Я использую asp.net webapi для возврата DTO с полями даты. Они сериализуются с использованием JSON.Net(в формате "2013-03-11T12: 37: 38,693" ).
Я хотел бы использовать фильтр, но в элементе INPUT, возможно ли это или я должен создать новый фильтр или директиву для выполнения этого?
// 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'}}
Есть ли какой-либо ярлык, который мне не хватает?
Ответы
Ответ 1
Вкратце: если вы хотите, чтобы ваши данные имели другое представление в представлении и в модели, вам понадобится директива, которую вы можете представить как двухстороннюю фильтр.
Ваша директива будет выглядеть примерно так:
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.
Ответ 2
Наличие разных значений в вашем поле ввода и в вашей модели идет вразрез с самой природой 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'};
});
Ответ 3
Если на вашем входе отображаются только данные
Если вам действительно нужен ввод для просто отображения некоторой информации, и это другой элемент, который изменяет модель Angular, вы можете сделать более легкое изменение.
Вместо написания новой директивы просто НЕ ИСПОЛЬЗУЙТЕ 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'}}" />
И работает как шарм:)
Ответ 4
Полный пример, который форматирует числа, вставляя пробелы каждые 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, '$1 ').reverse()
modelCtrl.$parsers.push (input) ->
return unless input?
input.replace(/\s/g, '')
Применение:
<input ng-model="price" intersperse/>
Пример Plunkr: http://plnkr.co/edit/qo0h9z
Ответ 5
Вам не нужно будет создавать новый фильтр с нуля, так как angular уже имеет встроенный фильтр для типов дат.
http://docs.angularjs.org/api/ng.filter:date
Я считаю, что именно то, что вам нужно.