Arrays & pureComputed values

2019-09-11 03:29发布

问题:

According to Knockout's documentation, one can use pureComputed to validate input fields.

The trouble seems to come when placing the observables bound to those input fields in an array (or observableArray).

this["values"] = []; // ko.observableArray([]);

And populating this array...

for(var $x=0; someArray[$x]!=undefined ;$x++){ 
  this["values"][$x]= ko.observable(someArray[$x]).extend(numeric: 0); 
}

Input fields are generated by KO's foreach, somewhat like this:

<Table>
  <!-- ko foreach: generate_series( 1, field_Proyecto() ) -->
  <Tr><Td data-bind="text: 'Quota number: '+$data+':'"></Td>
  <Td><Input Type="Text" Class="form-control" data-bind="textInput: $root.fee_temp_data[$index()]"></Td></Tr>
  <!-- /ko -->
</Table>

Using the example "numeric" extender provided by Knockout, the inputs stay in "0" and performs no changes.

Using this, inputs are forced to be numeric, but when a users types a non-digit character, all the values in the array becomes empty ("").

ko.extenders.numeric = function(target, option) {
  var to_number = ko.pureComputed({
    read: target,
    write: function(newValue){
      var current = target();
      $new = newValue.replace(/[\d]/ig, "");
      console.log($new);
      //$new = parseInt($new);
      //$new = $new.formatMoney(0, ".", ",");
      target( $new );
    }
  }).extend({ notify: "always" });

  to_number( target() );
  return to_number;
};

Also, "^\d" is supossed to match non-digits, but, as you can see I use \d and the code as is matches digits (in fact, you will see the console logs void values when integers are provided, but it will output the integer value in the input field).

generate_series simply outputs an array, given a range, also, this is the real function that initializes said observableArray.

this["generate_series"] = function($a, $b){

    this["fee_temp_data"] =[];
    this["fee"]( this["fees"][$b] );

    for(var $x=$a, $out=[];$x<=this["fees"][$b];$x++) { 
      $out.push($x); 
      this["fee_temp_data"].push( ko.observable("").extend( {numeric: ""} ) );
    }

    return $out;
  };

Here is a jsfiddle to describe my problem.

回答1:

You had a call to to_number in the definition of numeric that was fouling things up. I've made an updated fiddle that removes non-digits and either updates the target or notifies subscribers (as per the documentation page): http://jsfiddle.net/4r1nv1ft/2/