5

これは、vb.net の mvc3 Razor プロジェクトです。1) 1 列から 3 列、1 列から多数の行を含むことができる動的テーブルを作成する必要があります。 Ntd関数の実際の文字列と一緒に文字列を返すだけなので、戻り時にジャッキアップされます。これは、その時点で何が起こっているべきかを理解するためのものです...これらのチェックボックスを離れて生成する方法がわかりませんバインドできるので、コントローラーのポストメソッドが保存されます...ページ上のすべてのチェックボックスをダンプすると、すべてが正しく保存および更新されます。レイアウトは目が痛いだけです..

これが現在のビューです

@ModelType xxxxxx.CourseModel

@Code
    ViewData("Title") = "Edit Courses"
End Code

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"  type="text/javascript"></script>

@Using Html.BeginForm(Nothing, Nothing, FormMethod.Post, New With {.enctype = "multipart/form-data"})
    @Html.ValidationSummary(True)

    @<fieldset>
        <legend>Edit Courses</legend>
        @Html.HiddenFor(Function(model) model.cId)
        <table style="float: left">
            <tr>
                <th>Certification Bodies</th>
            </tr>
            <tr>
                @For _i As Integer = 0 To Model.Bodies.Count - 1
                    Dim i = _i
                    @<td>
                        @Html.CheckBoxFor(Function(model) model.Bodies(i).certSelected)
                        @Html.DisplayFor(Function(f) f.Bodies(i).certName)
                        @Html.HiddenFor(Function(model) model.Bodies(i).certBodyId)
                    </td>
                Next
            </tr>
            <tr>
                <th><input type="submit" value="Save" /></th>
            </tr>
        </table>
    </fieldset>
end using

これはヘルパーメソッドです

<Extension()> _
Public Function CreateCheckBoxTable(ByVal helper As HtmlHelper, ByVal d As List(Of CertBodyVM)) As MvcHtmlString
    Dim htmlDisplayer As String = Table()
    Dim counter As Integer = 0
    For Each item In d
        If counter = 0 Then
            htmlDisplayer = htmlDisplayer + NRow()
        End If
        counter += 1
        If Not counter >= 3 Then
            htmlDisplayer = htmlDisplayer + Ntd("@Html.CheckBoxFor(Function(model) model.Bodies(i).certSelected)@Html.DisplayFor(Function(f) f.Bodies(i).certName)@Html.HiddenFor(Function(model) model.Bodies(i).certBodyId)")
        Else
            counter = 0
            htmlDisplayer = htmlDisplayer + CRow()
        End If
    Next
    htmlDisplayer = htmlDisplayer + CTable()
    Dim x As MvcHtmlString = MvcHtmlString.Create(htmlDisplayer)
    Return x
End Function

Public Function Table() As String
    Return String.Format("<table>")
End Function
Public Function CTable() As String
    Return String.Format("</table>")
End Function
Public Function NRow() As String
    Return String.Format("<tr>")
End Function

Public Function TdEnd() As String
    Return String.Format("</td>")
End Function

Public Function CRow() As String
    Return String.Format("</tr>")
End Function

Public Function Ntd(ByVal text As String) As String
    Return String.Format("<td>{0}</td>", text)
End Function

ヘルパー メソッドを呼び出すには、for each ループとその内容を次のように置き換える予定です。

 @Html.CreateCheckBoxTable(Model.Bodies)

このメソッドは、正しい行と列を持つ適切なテーブルを生成していますが、チェックボックスで迷っています..

以下は、生成されている現在の出力です。

<tr><td><table><tr><td>@Html.CheckBoxFor(Function(model) model.Bodies(i).certSelected)@Html.DisplayFor(Function(f) f.Bodies(i).certName)@Html.HiddenFor(Function(model) model.Bodies(i).certBodyId)</td></table></td></tr>
4

2 に答える 2

4

コードは機能しません。ヘルパーでラムダ式を再構成する必要があります。また、このCreateCheckBoxTableヘルパーにCertBodyVMのリストだけでなくラムダ式を使用させて、このテーブルで使用する可能性のあるCheckBox(またはその他の入力要素)に適切な名前を付けることをお勧めします。

Public Module MyModule
    Private indexerMethod As MethodInfo = GetType(IList(Of CertBodyVM)).GetMethod("get_Item")
    Private certSelectedProperty As PropertyInfo = GetType(CertBodyVM).GetProperty("CertSelected")
    Private certNameProperty As PropertyInfo = GetType(CertBodyVM).GetProperty("CertName")
    Private certBodyIdProperty As PropertyInfo = GetType(CertBodyVM).GetProperty("CertBodyId")

    <Extension()> _
    Public Function CreateCheckBoxTable(Of TModel)(ByVal helper As HtmlHelper(Of TModel), ByVal ex As Expression(Of Func(Of TModel, IList(Of CertBodyVM)))) As IHtmlString
        Dim table = New TagBuilder("table")
        Dim metadata = ModelMetadata.FromLambdaExpression(ex, helper.ViewData)
        Dim bodies = CType(metadata.Model, List(Of CertBodyVM))
        Dim tableBody = New StringBuilder()
        For i = 0 To bodies.Count - 1
            Dim ex1 = MakePropertyExpression(Of TModel, Boolean)(ex, certSelectedProperty, i)
            Dim ex2 = MakePropertyExpression(Of TModel, String)(ex, certNameProperty, i)
            Dim ex3 = MakePropertyExpression(Of TModel, Integer)(ex, certBodyIdProperty, i)

            Dim tr = New TagBuilder("tr")
            Dim td = New TagBuilder("td")
            td.InnerHtml = String.Concat(
                helper.CheckBoxFor(ex1),
                helper.DisplayFor(ex2),
                helper.HiddenFor(ex3)
            )

            tr.InnerHtml = td.ToString()
            tableBody.Append(tr.ToString())
        Next
        table.InnerHtml = tableBody.ToString()

        Return New HtmlString(table.ToString())
    End Function

    Private Function MakePropertyExpression(Of TModel, TProperty)(ByRef ex As Expression(Of Func(Of TModel, IList(Of CertBodyVM))), ByRef pi As PropertyInfo, ByVal i As Integer) As Expression(Of Func(Of TModel, TProperty))
        Return Expression.Lambda(Of Func(Of TModel, TProperty))(
            Expression.Property(
                Expression.Call(ex.Body, indexerMethod, Expression.Constant(i)),
                pi
            ),
            ex.Parameters()
        )
    End Function
End Module

そして、あなたはそれをこのように使うことができます:

@ModelType xxxxxx.CourseModel
...
@Html.CreateCheckBoxTable(Function(x) x.Bodies)
于 2013-03-10T19:43:24.737 に答える