2017-06-16 21 views
0

クライアントの日時を変更できるように、datetimeサーバーセットのセットを計算するのは難しいです。 以下のコードは、負荷サーバーのデータとして機能し、サーバーに必要なisoフィールドを追加します。ノックアウトマッピングネストされた配列の計算されたプロパティ

ユーザーが日付/時刻入力フィールドを変更したときに、isoフィールドを動的に計算可能にするにはどうすればよいですか?これまで

ノックアウトJS:

var ViewModel = function() { 
    var self = this; 
    // ...other first-level observables and funct 

    function scadenzeNuove(payload) { 
    ko.mapping.fromJS(payload, {}, this); 

    this.iso = ko.pureComputed(function() { 
       var data_re = /^(\d{2})\/(\d{2})\/(\d{4})T(\d{2}):(\d{2})/; 
       if (!payload.data) { 
        return false; 
       }; 
       var data_string = payload.data; 

       if (!payload.ora) { 
        data_string = data_string + 'T00:00'; 
       } else { 
        data_string = data_string + 'T' + payload.ora; 
       }; 

       var data_match = data_re.exec(data_string) ? data_re.exec(data_string) : false; 
       if (!data_match) { return false; }; 
       var data = new Date(data_match[3], data_match[2]-1, data_match[1], data_match[4], data_match[5]) 
       return data; 
    }, this); 

    }; 
    var scadenzeNuoveMapping = { 
     create: function(options) { 
      return new scadenzeNuove(options.data); 
     }, 
    }; 

    self.scadenzeNuove = ko.observableArray(); 
    self.compScadenze = function(form) { 
    $.getJSON('{{ compute_scadenza }}', $(form).serialize(), function(data){ 
     ko.mapping.fromJS(data, scadenzeNuoveMapping, self.scadenzeNuove); 
    }); 
    }; 
}; 
var vm = new ViewModel() 
ko.applyBindings(vm); 

HTML:

<div data-bind="if: scadenzeNuove"> 
     <ul data-bind="foreach: scadenzeNuove"> 
     <li> 
      <span data-bind="text: iso().toLocaleFormat()"></span> 
      <input type="text" name="n_data" data-bind="value: data"> 
      <input type="text" name="n_ora" data-bind="value: ora"> 
      <input type="text" name="n_desc" data-bind="value: desc"> 
     </li> 
     </ul> 
</div> 
+0

私は問題があると仮定し、ISOプロパティDそのしかし、私は正しいタイミングをどのように適用するのかわかりません... – user2154587

+0

[このレスポンス](https:/)に示すように、私は裸のko.computedを使用しようとしましたが、 /stackoverflow.com/questions/10906252/knockout-mapping-with-computed-fields?rq=1)しかし、まだ動作していません。isoフィールドはコンポーネントのフィールド値が変更されても更新されません。 – user2154587

答えて

0

...あなたがDate秒で作業している場合は、いくつかの固体テストを書くかmoment.jsを使用するか私の障害をアドバイスしたい:私は言及しました静的データ​​代わりに、動的に観察parentの:

function ScadenzeNuove(payload) { 
    var parent = this; 
    ko.mapping.fromJS(payload, {}, parent); 

    parent.iso = ko.pureComputed(function() { 
     var data_re = /^(\d{2})\/(\d{2})\/(\d{4})T(\d{2}):(\d{2})/; 
     if (!parent.data()) { 
      console.log("Not entered any date"); 
      return false; 
     }; 
     var data_string = parent.data(); 

     if (!parent.ora()) { 
      data_string = data_string + 'T00:00'; 
     } else { 
      data_string = data_string + 'T' + parent.ora(); 
     }; 

     var data_match = data_re.exec(data_string) ? data_re.exec(data_string) : false; 
     if (!data_match) { 
      console.log('Not a valid date format'); 
      return false; 
     }; 

     console.log(data_match); 

     // Array [ "08/06/2017T23:50:00", "08", "06", "2017", "23", "50" ] 
     var data = new Date(data_match[3], data_match[2]-1, data_match[1], data_match[4], data_match[5]) 
     console.log(data.toLocaleFormat()); 
     console.log(data.getTimezoneOffset()); 
     return data; 
    }, parent); 


    parent.toCal = ko.observable(false); 
}; 
0

私は離れた年、月、などでのviewmodelにISO文字列から行くために、既定のコンストラクタを使用したい観測最初。

次に、計算されたisoStringプロパティを定義して、これらをサーバーに送信できる文字列に再結合することができます。

私は強く

const DateTimeSelection = function(isoString) { 
 
    const date = new Date(isoString); 
 
    
 
    this.year = ko.observable(
 
    date.getFullYear() 
 
).extend({ num: true }); 
 
    
 
    this.month = ko.observable(
 
    date.getMonth() 
 
).extend({ num: true }); 
 
    
 
    this.date = ko.observable(
 
    date.getDate() 
 
).extend({ num: true }); 
 
    
 
    this.hour = ko.observable(
 
    date.getHours() 
 
).extend({ num: true }); 
 

 
    this.isoString = ko.pureComputed(() => 
 
    new Date(
 
     this.year(), this.month(), this.date(), this.hour() 
 
    ).toISOString() 
 
); 
 
    
 
    this.hasChanged = ko.pureComputed(() => 
 
    this.isoString() !== isoString 
 
); 
 
}; 
 

 

 
ko.extenders.numeric = function(target) { 
 
    return ko.computed({ 
 
    read: target, 
 
    write: x => target(Number(x)) 
 
    }); 
 
}; 
 

 
const initialServerData = "2017-06-16T14:00:00.000Z"; 
 
const vm = new DateTimeSelection(initialServerData); 
 

 
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 
<input type="number" data-bind="textInput: year"> 
 
<input type="number" data-bind="textInput: month"> 
 
<input type="number" data-bind="textInput: date"> 
 
<input type="number" data-bind="textInput: hour"> 
 

 

 

 
<div data-bind="text: 'output ' + isoString()"></div> 
 
<div data-bind="ifnot: hasChanged" style="color: green">Has not been altered by user</div> 
 
<div data-bind="if: hasChanged" style="color: red">Has been altered by user</div>

+0

私の質問はjson配列をko.mapping.fromJSでマッピングすることです.js datetimesを使って、私が – user2154587

+0

にするよりも混乱させないようにしています。私の見解を非常にうまく説明していなかったと思います。あなたのビューモデルとあなたのサーバーモデルとの間の通信にISO日付文字列を使用する方が簡単だということです。つまり、 'DateTime' ISO文字列を受け取って' year'、 'month'などの入力を作成し、最後にISO文字列にキャストしたビューモデルを作成します。また、正規表現を使ってISO文字列を解析すると、実際にこの種の問題を解決するために用意された言語機能を使用するよりも「js datetimesが混乱している」と言います。 – user3297291

+0

しかし、私は正しいjavascript関数の範囲を管理していなかったので、私のコードが壊れた。 – user2154587

関連する問題