2017-08-09 789 views
1

我正在爲應該看起來很簡單的過程而苦苦掙扎。將序列化的JSON字符串解析爲TS對象

在「geolocate.ts」函數「setData」中,模型索引?從「model.flightplan」或「model.config」引用時,Chrome調試器會顯示「flightplan」和「config」爲「未定義」。即使在調試器中展開時,「模型」對象本身似乎也很好。

任何想法或指針將是非常讚賞;)

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到'飛行計劃',也用於配置。如果這樣做不起作用,那麼解析JSON到你的模型可能有問題 –

回答

1

第一個問題似乎是,你正在訪問像flightplanconfig場,而在JSON中,它們是FlightPlanConfig。這就是爲什麼你得到undefined s。

後稍微比較大的問題,這將主要咬你,如果你打算添加方法到類,是由JSON.parse生產的東西是一個簡單的JavaScript對象,而ConfigFlightPlan等也是類,實例他們將屬於那個階層。所以如果你有這樣的事情:

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' 

所以這兩個在結構上是等效的,但不會在功能上等效。即使做了TS演員,也不會像x那樣在y上調用功能。如果這些都是簡單的DTO,那可以。但是,如果沒有,你需要明確這一點,並做從JS對象翻譯到您的應用程序的另一個步驟。


無恥插頭:我寫raynor自動完成這一確切的過程 - 一個DTO類型和更有用的JavaScript類之間進行轉換的。


您也可以在.NET上側配置的JSON序列字段名從PascalCase轉換爲「camelCase`。

+0

謝謝 - 我將調查consisisteny的命名問題。我在C#/ TS/JS中發現了「problamatic」的名字,因爲它們似乎都有不同的公共/私人等的命名標準! - 它發送我的Resharper和Lints瘋狂!我正在使用「TypeScriptSyntaxPaste」從C#類創建d.ts文件,但會隨時給raynor一個外觀。 – JcMaltaDev

+0

謝謝。在JSON序列化過程中的確是一個案例問題。使用CamelCasePropertyNamesContractResolver「解決」了這個問題。 這些對象是(現在)簡單的DTO,但我已將書籤作爲未來參考的Raynor。再次感謝。 – JcMaltaDev

相關問題