2017-08-09 787 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

相关问题