Angular ngModel different view and value

北慕城南 提交于 2019-12-24 16:00:07

问题


Does ngModel controller in directive have any option to show something different from ngModel value in view, or i have to write custom html directive for input?
I wrote a comma-separator directive. everything is fine, but ngModel value change from Number to String with ,.
I mean can i have input with value 1000000 but it shows 1,000,000 in view?

Update:
In the input box shows 1,000,000, but its value be 1000000.

Update 2
I know about $formatters and $parsers. but the problem is $formatters doesn't harm real value, but it works when ngModel changed directly, not by typing in input element, and $parsers watch all changes, but change real value too.


回答1:


use filter to achieve this

HTML

<div ng-controller="demoController">

<input type="text" value="{{val | number}}">
</div>

controller:

var app = angular.module('demoApp', []);

app.controller('demoController', ['$scope', '$http', function($scope, $http, $cookies, $location){
     $scope.val = 1000000;
}]);



回答2:


You can use ngModel.$formatters:

ngModel.$formatters.push(function (number) {
    return convertToCommaSeparatedString(number);
});

In this case model will remain number but input will show formatted string.

See documentation




回答3:


To answer your question...

"I mean can i have input with value 1000000 but it shows 1,000,000 in view?"

I'm assuming you want a Number as the model, but a comma separated String in the input as the user types. Based on this assumption, I can answer your question with a YES, you can do this; here's how...

Link: CodePen Working Example

NOTE

This example is created in a way that will only allow digits to be entered in to the input. You can change this as you like in each $filter.

Also a word of caution to only use filters that you create that clean the data when it enters the filter. Angular filters are mostly for static values, so they don't work when you want to filter values as they are entered.

i.e. In this case, if we didn't clean the data by removing (/\D/g) all non-digits, we would be splitting, joining, and reversing with commas (and anything else) in the string and the result would crash.

HTML

<div ng-app="myApp" ng-controller="myCtrl">
  <input ng-model="inputValueModel" type="text" format-my-view-only />
  Model Value is Number: {{ inputValueModel || "Empty" }}
</div>

JS

var app = angular.module("myApp", []).controller("myCtrl", function($scope){});

app.directive("formatMyViewOnly", function($filter){
// You don't have to use $filter, you can do inline work as well as
// functions inside of this directive. I use $filters for code reuse.

  return {
    require: "ngModel",
    restrict: "A",
    link: function(scope, elem, attrs, input){

      input.$parsers.push(function(value){
        value = $filter("addCommas")(value);
        input.$setViewValue(value); // Set view value.
        input.$render();
        // Then return Number to model.
        return +$filter("onlyNumbers")(value); // Unary Operator converts string to Number. Remove it if you want model to be a string as well.
      });
    } // end link.
  }; // end return.
});


app.filter('onlyNumbers', function(){
  return function(numbers){
    if(invalid(numbers)){ return ""; }
    return numbers.replace(/\D/g, "");
  };

  function invalid(number){
    return !number || notString(number) || noNumbersExists(number);
  }

  function notString(string){
    return typeof string != "string";
  }

  function noNumbersExists(number){
    return number.replace(/\D/g, "").length === 0;
  }
});

app.filter('addCommas', function(){
  return function(stringOfNums){
    if(invalid(stringOfNums)){ return ""; }
    return commaSeparated(stringOfNums.replace(/\D/g, ""));
  };

  function commaSeparated(numbers){
    if(!numbers){return "";}
    return numbers.split("").reverse().join("")
      .match(/.{1,3}/g).reverse().join(",");
  }

  function invalid(number){
    return !number || notString(number) || noNumbersExists(number);
  }

  function notString(string){
    return typeof string != "string";
  }

  function noNumbersExists(number){
    return number.replace(/\D/g, "").length === 0;
  }
});


来源:https://stackoverflow.com/questions/35066118/angular-ngmodel-different-view-and-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!