2013-09-22 7 views
10

Szukałem wszędzie do tego. Każde przepełnienie stosu, które ma odpowiedź, w rzeczywistości nie działa. To samo z przykładami lub przykładami grup w Google z dla kanciastych, w tym z dokumentami.

Wydaje się proste. Chcę wywołać funkcję na wejściu dla każdego klawisza naciśniętego przez użytkownika.

proste wejście z NG-modelu

<input class="form-control" ng-model="model.thisisnotfun" formatter type="text" required> 

Według wszystko czytam. $ formatters powinno zaktualizować wartość z modelu do widoku wywołującego dowolne funkcje z tablicy $ formatters. Nigdy nie są wywoływane, gdy wpisuję w polu wejściowym.

.directive('formatter', function ($filter, $parse) { 
    return { 
     require: 'ngModel', 

     link: function (scope, element, attrs, ngModel) { 

      ngModel.$formatters.push(
       function (value) { 
        console.log('this only gets called on page load'); 
       } 
      ); 
     } 
    }; 
}) 

Wiem, że istnieje wiele niestandardowych sposobów, aby to zrobić, co już zrobiłem. Nie potrzebuję żadnej pracy, po prostu chcę wiedzieć, jak poprawnie używać formatu $ formatters, aby "formatować" dane widoku.

bardzo proste jsfiddle http://jsfiddle.net/fh7sB/4/

Dzięki za wszelką pomoc.

+0

Nie widzę '$ formatter' w dokumentacji angularjs. Czy możesz mi w tym pomóc? – Abilash

+0

Również plunk pomoże – Abilash

+0

pewnie źle post jeden. Dokumenty są dla ngModelController http://docs-angularjs-org-dev.appspot.com/api/ng.directive:ngModel.NgModelController –

Odpowiedz

9

Wywołanie po zaktualizowaniu modelu model w celu sformatowania wartości, która ma zostać wyświetlona użytkownikowi. $parsers działa odwrotnie, tj. Przekształca wartość z ciągu widoku na model rzeczywisty, np. numer.

W rozwidlonym skrzypcach tutaj: http://jsfiddle.net/9tuCz/ naciśnij przycisk; zmienia model i ponownie odpala numer $formatters.

+1

Dziękuję, wymyśliłem to podczas wszystkich testów i od tego czasu zastanawiałem się, jak sprawić, by formatery $ formatters były uruchamiane z poziomu dyrektywy, ustawiając wartość $ modelValue tak jak przycisk ma. Czy wiesz, jak to się stało, to jest mój cel. –

+0

Dodatkowo podczas moich testów przycisk zwolni tylko formater $, jeśli wejście nie jest już takie samo. –

+0

Odpowiedziałeś, dlaczego nie zaczęto wywoływać formaterów $, co jest poprawne. Mimo że nie pomogło to mojemu problemowi, odpowiedział, że tak źle to zaznaczę. Jeśli ktoś potrzebuje dyrektywy, może spojrzeć na moją odpowiedź. –

0

Upewnij się, że zwracasz prawidłową wartość ze swoich funkcji.

Prawdopodobnie dzieje się tak, ponieważ analizator składni zwraca za każdym razem tę samą wartość, formater zakłada, że ​​sformatowane dane wyjściowe nie ulegną zmianie, więc pominie połączenie.

+0

Podoba mi się ten pomysł. Czy możesz zaktualizować moje skrzypce, żeby to udowodnić? Zaakceptowałbym tę odpowiedź w mgnieniu oka, odkąd waliłem w głowę od wielu godzin. –

+0

Nie jestem dokładnie pewien, co mówisz. Oto zaktualizowane skrzypce, czy to masz na myśli, czy możesz to naprawić? http://jsfiddle.net/bDZf3/3/ –

10

Nie mogłem uzyskać funkcji formaterów $ $ do działania tak, jak chciałem. Nie mogłem też znaleźć jednego przykładu tego, czego szukałem w dowolnym miejscu, więc zamierzam opublikować moją odpowiedź, na wypadek gdyby ktoś jej potrzebował.

Jest to dyrektywa formatowania nam walutę w polach wejściowych z NG-modelu

.directive('uiCurrency', function ($filter, $parse) { 
    return { 
     require: 'ngModel', 
     restrict: 'A', 
     link: function (scope, element, attrs, ngModel) { 

      function parse(viewValue, noRender) { 
       if (!viewValue) 
        return viewValue; 

       // strips all non digits leaving periods. 
       var clean = viewValue.toString().replace(/[^0-9.]+/g, '').replace(/\.{2,}/, '.'); 

       // case for users entering multiple periods throughout the number 
       var dotSplit = clean.split('.'); 
       if (dotSplit.length > 2) { 
        clean = dotSplit[0] + '.' + dotSplit[1].slice(0, 2); 
       } else if (dotSplit.length == 2) { 
        clean = dotSplit[0] + '.' + dotSplit[1].slice(0, 2); 
       } 

       if (!noRender) 
        ngModel.$render(); 
       return clean; 
      } 

      ngModel.$parsers.unshift(parse); 

      ngModel.$render = function() { 
       console.log('viewValue', ngModel.$viewValue); 
       console.log('modelValue', ngModel.$modelValue); 
       var clean = parse(ngModel.$viewValue, true); 
       if (!clean) 
        return; 

       var currencyValue, 
        dotSplit = clean.split('.'); 

       // todo: refactor, this is ugly 
       if (clean[clean.length-1] === '.') { 
        currencyValue = '$' + $filter('number')(parseFloat(clean)) + '.'; 

       } else if (clean.indexOf('.') != -1 && dotSplit[dotSplit.length - 1].length == 1) { 
        currencyValue = '$' + $filter('number')(parseFloat(clean), 1); 
       } else if (clean.indexOf('.') != -1 && dotSplit[dotSplit.length - 1].length == 1) { 
        currencyValue = '$' + $filter('number')(parseFloat(clean), 2); 
       } else { 
        currencyValue = '$' + $filter('number')(parseFloat(clean)); 
       } 

       element.val(currencyValue); 
      }; 

     } 
    }; 
}) 
+1

Nie wszyscy bohaterowie noszą płaszcze. Dziękuję Ci. –

+0

to powinna być najlepsza odpowiedź – Nooblike

Powiązane problemy