Passing data in view model to controller via kendo

2019-09-14 05:00发布

问题:

So far, I'm just trying to instantiate my kendogrid and passing through values from my view model. I got the following piece of code from Telerik's documentation for vb.net. The thing is, an exception is thrown from .Grid -> "Type parameter for public overridable overloads function grid(of T as a class) as a gridbuilder(of t) cannot be inferred"

Html.Kendo().Grid().Name("kendogrid")

I'm not sure what this error means and I don't know how to go about fixing it.

View

$(document).ready(function () {
    var dataSource = new kendo.data.DataSource({
        transport: {
            read: {
                url: "TestAjax",
                dataType: "json",
                type: "GET",
            },
            update: {
                url: "update",
                dataType: "json",
                type: "POST"
            },
            create: {
                url: "CreateInvoiceRecord",
                dataType: "json",
                type: "GET",
            },
            parameterMap: function (options, operation) {
                console.log(operation);
                console.log(options);
                if (operation !== "read" && options.models) {
                    return { models: kendo.stringify(options.models) };
                }
            }
        },
        batch: true,
        pageSize: 20,
        schema: {
            model: {
                id: "itemID",
                fields: {
                    ItemName: { type: "string" },
                    Amount: { type: "number", editable: false, validation: { required: true } },
                    ProductLine: { type: "string" },
                    Status: { type: "string" },
                }
            }
        },
        aggregate: [{ field: "Amount", aggregate: "sum" }
        ]
    });
    $("#kendogrid").kendoGrid({
        DataSource: dataSource,
        pageable:  true,
        height: 550,
        toolbar: ["create", "save"],
        columns: [
            { field: "ItemName", title: "Item", width: "150px" },
            { field: "Amount", title: "Amount", format: "{0:c}", width: "100px", aggregates: ["sum"], footerTemplate: "Total Amount: #=sum#" },
            { field: "ProductLine", title: "Product Line", width: "150px", editor: productLineDropDownEditor},
            { field:  "Status", title: "Status", width: "150px", editor: statusDropDownEditor },
            { command:  "Update", title: "Update" , width:"150px"}],
        editable: true
        });
});

Model

Public Class MyViewModel
    Public Property id As String
    Public Property id2 As String
End Class

回答1:

The VB grid syntax from http://docs.telerik.com/kendo-ui/aspnet-mvc/vb#grid is:

Html.Kendo().Grid(Of YourViewModelClassThatYouWantToBindTheGridTo)() _
    .Name("grid") _
    ...additional configuration.

You are missing the part where you tell the grid what type of object you are binding to(the "Of NameOfYourClass" part.

You should post your whole grid definition.

Also...C# syntax is sooooo much cleaner(I know that's not helpful).

Edit

OK, so this question isn't about the correct VB.NET Razor syntax anymore....

This is how you get "extra" data passed to the controller methods from a dataSource: you use the dataSource.transport.read.data configuration (http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.read.data)

Using an object:

transport: {
        read: {
            url: "TestAjax",
            dataType: "json",
            type: "GET",
            data: {
                parameterToPassToReadAction: valueYouWantToPassToReadAction
            }
        },

Using a function:

transport: {
        read: {
            url: "TestAjax",
            dataType: "json",
            type: "GET",
            data: extraDataFunction
        },

function extraDataFunction () {
    return {
        parameterToPassToReadAction: valueYouWantToPassToReadAction
    };
}

Where parameterToPassToReadAction is the name of the parameter in your server method and valueYouWantToPassToReadAction is the value you want it to be...which is stored where ever you stored it when the page loaded. If it is in a ViewModel of your vbhtml file and your javascript is in the script block of that same file, the syntax will be something like:

function extraDataFunction () {
    return {
        parameterToPassToReadAction: @Model.FieldYouWantToSend
    };
}

But it is not clear where you have this value stored.



回答2:

Finally got what I wanted working using a hack for create and then ajax for read. Not totally sure why this works the way it does so I'll need to look into it some more. I needed to pass parameters to controllers that are connected to kendogrid - specifically the read and create operations. I created a view model to store the values that I obtained from my Index controller and then used the view model to pass the values from kendogrid to the read and create operation controllers. For some reason, I was only able to pass parameters to the read operation using ajax.

Note: Still not the best solution. It calls readData controller twice and I don't want that.

Javascript

<Script>
    $(document).ready(function () {
        var dataSource = new kendo.data.DataSource({
            transport: {
                read: {    
                    url: "readData",
                    dataType: "json",
                    type: "GET",                  
                },
                create: {
                    url: "CreateInvoiceRecord?trxid=@Model.id2&bcid=@Model.id",
                    dataType: "json",
                    type: "GET",
                },
                parameterMap: function (options, operation) {
                    if (operation !== "read" && options.models) {
                        return { models: kendo.stringify(options.models) };
                    }
                }
            },
            batch: true,
            pageSize: 20,
            schema: {
                model: {
                    id: "itemID",
                    fields: {
                        ItemName: { type: "string" },
                        Amount: { type: "number", validation: { required: true } },
                        ProductLine: { type: "string" },
                        Status: { type: "string" }
                    }
                }
            },
            aggregate: [{ field: "Amount", aggregate: "sum" }]
        });
        $("#kendogrid").kendoGrid({
            dataSource: dataSource,
            navigatable: true,
            pageable:  true,
            height: 550,
            toolbar: ["create", "save"],
            columns: [
                { field: "ItemName", title: "Item", width: "150px" },
                { field: "Amount", title: "Amount", format: "{0:c}", width: "100px", aggregates: ["sum"], footerTemplate: "Total Amount: #=sum#" },
                { field: "ProductLine", title: "Product Line", width: "150px", editor: productLineDropDownEditor},
                { field:  "Status", title: "Status", width: "150px", editor: statusDropDownEditor },
                { command:  "Update", title: "Update" , width:"150px"}],
            editable: true
        });
    });
    function productLineDropDownEditor(container, options) {
            $('<input required name="' + options.field + '"/>')
            .appendTo(container)
            .kendoDropDownList({              
                autoBind: false,
                valuePrimitive: true,
                dataTextField: "name",
                dataValueField: "name",
                dataSource: {
                    transport: {
                        read: {
                            url: "/Customs/getProdLines",
                            dataType: "json"
                        }
                    },
                    schema: {
                        data: "Data",
                        model: {
                            fields: {}
                        }
                    },
                }
            });
    }
    function statusDropDownEditor(container, options) {
            var data = [
                { text: "Active", value: "1" },
                { text: "Paid", value: "2" },
                { text: "Cancelled", value: "3" }
            ]
            $('<input required name="' + options.field + '"/>')
            .appendTo(container)
            .kendoDropDownList({
                valuePrimitive: true,
                dataTextField: "text",
                dataValueField: "value",
                autobind: false,
                dataSource: data
            });
    }
    //function testAjax() {     
    //}
    //data: { 'name': ItemName, 'amount': Amount, 'prodline': ProductLine, 'status': Status },
    $.ajax({
        type: "Get",
        data: { id: "@Model.id", id2:"@Model.id2" },
        url: "readData/",
        dataType: "json",
        success: function (itemList) {
            console.log(itemList);
        }
    });
</script>

Model

Public Class MyViewModel
    Public Property id As String
    Public Property id2 As String
End Class