开发者

EXT Js Complex JSON Response Handling : Grid Insertion

开发者 https://www.devze.com 2023-02-27 01:43 出处:网络
Hello I am trying to insert a JSON record into the grid dynamically. My server response is as below : {

Hello I am trying to insert a JSON record into the grid dynamically. My server response is as below :

{
    "studentDetails":{
        "status":"ACTIVE",
        "subject":"MATH",
        "paymentOptions":"EFT",
        "idStudent":71,
        "firstName":"Alli",
        "lastName":"Alli",
        "middleName":"Alli",
        "grade":"A",
        "kumonLevel":"FK",
        "parentId":68,
        "userId":1,
        "parentBean":{
            "parentFirstName":"Alli",
            "idParent":68,
            "parentMiddleName":"Alli",
            "parentLastName":"Alli",
            "parentEmailId":"haigopi@gmail.com",
            "parentPhoneNumber":"3173797945"},
        "startTimeSlot":"12:00 AM",
        "endTimeSlot":"12:15 AM",
        "dob":"2012-07-04"},
    "success":true
}

A student having parentDetails as a seperate object in the above response.

at my client I did the following : i had a grid with the below configuration :

var studentRecord = Ext.data.Record.create( [ {
    name : 'firstName',
    type : 'string'
}, {
    name : 'lastName',
    type : 'string'
}, {
    name : 'middleName',
    type : 'string'
}, {
    name : 'grade',
    type : 'string'
}, {
    name : 'kumonLevel',
    type : 'string'
}, {
    name : 'startTimeSlot',
    type : 'string'
}, {
    name : 'endTimeSlot',
    type : 'string'
}, {
    name : 'subject',
    type : 'string'
}, {
    name : 'dob',
    type : 'date'
}, {
    name : 'status',
    type : 'string'
}, {
    name : 'paymentOptions',
    type : 'string'
}, {
    name : 'parentFirstName',
    mapping : 'parentBean.parentFirstName',
    type : 'string'
}, {
    name : 'parentLastName',
    mapping : "parentBean['parentLastName']",
    type : 'string'
}, {
    name : 'parentMiddleName',
    mapping : 'parentBean.parentMiddleName',
    type : 'string'
}, {
    name : 'parentPhoneNumber',
    mapping : 'parentBean.parentPhoneNumber',
    type : 'Strin开发者_C百科g'
}, {
    name : 'parentEmailId',
    mapping : 'parentBean.parentEmailId',
    type : 'string'
} ]);

var myProxy = new Ext.data.HttpProxy( {
    method : 'GET',
    url : 'listActiveStudents.do'
});
var studentsListReader = new Ext.data.JsonReader( {
    successProperty : 'success',
    root : 'studentDetails',
    idProperty : 'idStudent'
}, studentRecord);

var studentDS = new Ext.data.Store( {
    proxy : myProxy,
    autoLoad : true,
    totalProperty : 'total',
    reader : studentsListReader
});

upon data receiving from the server I did the following :

handler : function() {
    studentForm.getForm().submit({
        url : 'createStudent.do',
        waitMsg : 'Saving Data...',
        submitEmptyText : false,
        success : function(form, action) {
            win.close();
            var studentDetail = action.result.studentDetails;
            var xyz = new studentDS.recordType(studentDetail, 0);
            studentDS.insert(0,xyz);
        }
    });
}

The problem what I am facing here is :

When the record is inserted the parentDetails are not showing up in the grid. Seems, the mapping is not working properly while inserting. Where as while loading the grid initially it renders perfectly. I created the record well which shows in firefox debbuger with valid values too.

could any one guide me please?


This is a very tricky issue. but I found an easy (but dirty) solution, which you just need to edit the line where you create your record, from this:

var xyz = new studentDS.recordType(studentDetail, 0);

to this:

var xyz = new studentDS.recordType(
    studentDS.reader.extractValues(
        studentDetail, 
        studentDS.fields.items,
        studentDS.fields.length
    ), studentDetail.idStudent); //use the idStudent of the studentDetail, so the id of the newly created record equals to your idStudent

And here is why

So after tracing the calling stack, I found an interesting differences between the records you loaded from Store, and the record that you created through your new studentDS.recordType.

Look at the differences:

//This is the record created from Store Load event
    dob: Wed Jul 04 2012 00:00:00 GMT+0800 (Malay Peninsula Standard Time)
    endTimeSlot: "12:15 AM"
    firstName: "Alli"
    grade: "A"
    kumonLevel: "FK"
    lastName: "Alli"
    middleName: "Alli"
    parentEmailId: "haigopi@gmail.com"
    parentFirstName: "Alli"
    parentLastName: "Alli"
    parentMiddleName: "Alli"
    parentPhoneNumber: "3173797945"
    paymentOptions: "EFT"
    startTimeSlot: "12:00 AM"
    status: "ACTIVE"
    subject: "MATH"
    __proto__: Object

//This is the record created from your studentDS.recordType
    dob: "2012-07-04"
    endTimeSlot: "12:15 AM"
    firstName: "Alli"
    grade: "A"
    idStudent: 80
    kumonLevel: "FK"
    lastName: "Alli"
    middleName: "Alli"
    parentBean: Object
        idParent: 68
        parentEmailId: "haigopi@gmail.com"
        parentFirstName: "Alli"
        parentLastName: "Alli"
        parentMiddleName: "Alli"
        parentPhoneNumber: "3173797945"
        __proto__: Object
    parentId: 68
    paymentOptions: "EFT"
    startTimeSlot: "12:00 AM"
    status: "ACTIVE"
    subject: "MATH"
    userId: 1
    __proto__: Object

In fact, while you load your data, your JsonStore and JsonReader did a dirty hack to your loaded data. They linearize your data. They move all your data from your parentBean to the root of the record.data, so while rendering the grid, your grid can be rendered correctly.

To know how they render your grid, check the code at Line 827 of GridView.js

meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);

Notice how the GridView is capturing the values. They use record.data[column.name] to get the value of each fields, and this is where all your parent* report undefined.

And so to know how they linearize your codes, you can check line 157 of DataReader.js

var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
//where:
//n = your raw json object
//fi = the field items
//fl = the field length

And in fact the new Record they used here is identical with your new studentDS.recordType, with the exception that they extractValues for you on behalf, and clearly you did not do it because it's not obvious to do so.

Got it? Hope the explanation is clear enough.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号