2017-08-09 24 views
1

非常に簡単な手順であると思われる部分に苦労しています。JSON文字列をTSオブジェクトにデシリアライズ

"geolocate.ts"関数 "setData"では、モデルのインデックスは? "flightplan"と "config"は、 "model.flightplan"または "model.config"から参照されるときにChromeデバッガによって「未定義」と表示されます。 "モデル"オブジェクト自体は、デバッガで展開しても問題ないと思われます。

任意の考えやポインタを非常に高く評価されるだろう;)

geolocate.d.ts

export class FmsFlightPlan { 
    public status: string[]; 
    ... 
} 

export class Config { 
    public airportIcon: IconSettings; 
    ... 
} 

export class InitModel { 
    public config: Config; 
    public flightplan: FmsFlightPlan; 
} 

geolocate.ts

import * as passedData from "./geoLocate.d"; 

let config: passedData.Config; 
let flightPlan: passedData.FmsFlightPlan; 

export function setModel(json: string): void { 
    console.log(json); // '{"Config": { "AirportIcon": {...} ...}, {"Flightplan": {"Status": [], ... } ...}' --- As expected (JSONlint OK) 

    const model: passedData.InitModel = JSON.parse(json); 
    console.log(model); // Chrome console: {Config: {…}, Flightplan: {…}} 

    flightPlan = model.flightplan; // flightPlan and config are assigned "undefined" 
    config = model.config;  // "model" looks OK and Intellisense works. 

    flightplanDraw(); 
} 

TSCはjavascriptのを生成

function setModel(o) { 
    console.log(o); 
    var e = JSON.parse(o); 
    console.log(e), flightPlan = e.flightplan, config = e.config, flightplanDraw() 
} 

.NETのコアビューJavascriptを

function gmapsReady() { 

    initMap(); 
    $.getJSON("/Home/GetConfig", 
     null, 
     function(data) { 
      setModel(data); 
     }); 
} 

.NET MVCコントローラ

public JsonResult GetConfig() 
{ 
    // Load fplan and config objects 
    ... 
    ... 

    InitModel initModel = new InitModel 
    { 
     Flightplan = fplan, 
     Config = _config 
    }; 

    string json = JsonConvert.SerializeObject(initModel); 
    return new JsonResult(json); 
} 
+0

'flightPlan = model.Flightplan'を試して、その名前が大文字と完全に同じであることを確認してください。 JS内のJSONは大文字と小文字を区別します( –

+0

@ Helder De Baere:提案に感謝していますが、model.Flightplanを使用するとTSCコンパイルエラーが発生する(期待どおり) – JcMaltaDev

+1

次に、私はあなたの「flightplan」の名前を変更することをお勧めしますInitModelを 'Flightplan'に設定し、Configにも適用します。それがうまくいかない場合は、おそらくJSONのモデルを解析する際に何か問題があります –

答えて

1

最初の問題は、一方で、flightplanconfigなどの分野にアクセスしていることのようですJSONではFlightPlanConfigです。だからあなたはundefinedを得ています。

あなたのクラスにメソッドを追加することを予定している場合、主にあなたをかむことの後に大きめの問題は、ConfigFlightPlanなどのに対し、クラス、およびのインスタンスがあり、JSON.parseによって生成さのものは、簡単なJavaScriptオブジェクトであるということです彼らはそのクラスに属するだろう。したがって、次のようなものがある場合:

let x = new Config(); 
x.airportIcon = 'foo'; 
console.log(x.constructor); // Prints 'Config' 
let y = JSON.parse('{"airportIcon": "foo"}'); 
console.log(y.constructor); // Prints 'Object something or other' 

したがって、2つは構造的には同等ですが、機能的には同等ではありません。 TSキャストを実行しても、xと同じようにyの機能を呼び出すことはできません。これらが単純なDTOであればOKです。しかし、そうでない場合は、これについて明示して、JSオブジェクトからアプリケーションに変換する別のステップを実行する必要があります。


恥知らずなプラグイン:私はこの正確なプロセスを自動化するraynorを書いた - DTOタイプと、より便利なJavaScriptクラスの間で変換します。


またcamelCase`」にPascalCaseからフィールド名を変換するために、.NET側でJSONシリアライザを構成することができます。

+0

ありがとうございます。私はconsisistenyの命名問題を調査します。私はC#/ TS/JSの名前は "problamatic"なので、公的/私的な名前付けの基準が違うようです。 - それは私のResharperとLintsを狂って送ります!私は "TypeScriptSyntaxPaste"を使用してC#クラスからd.tsファイルを作成していますが、確かにraynorに一見を与えます。 – JcMaltaDev

+0

ありがとうございます。それは実際にJSONのシリアル化の間のケースの問題でした。 CamelCasePropertyNamesContractResolverを使用して問題を解決しました。 これらのオブジェクトは(今のところ)単純なDTOですが、私は後で参照できるようにraynorをブックマークしています。再度、感謝します。 – JcMaltaDev

関連する問題