2

HTMLフォームで、通常のプリミティブ型をモデルにバインドするのと同じ方法で、jqueryコントロール(tokeninputなど)をどのようにバインドしますか?私はこれを行う方法を見つけるのに苦労しており、カスタムテンプレートなどを使用できることは知っていますが、jqueryプラグインには何もありません。

具体的には、tokenInputを使用しています。こちら(http://loopj.com/jquery-tokeninput/)を参照してください。これは、標準のHTMLテキスト入力に対して適用するjQueryコードです。キーを押すたびに、作成者のリストを返すためにコントローラーに移動します。作成者を事前入力することもできます。HTML5のデータタグを使用して、コントロールを事前入力します。

 $("#AUTHORs").tokenInput('/author/getauthors/', {
        hintText: "Enter surname",
        searchingText: "Searching...",
        preventDuplicates: true,
        allowCustomEntry: true,
        highlightDuplicates: false,
        tokenDelimiter: "*",
        resultsLimit: 10,
        theme: "facebook",
        prePopulate: $('#AUTHORs').data('AUTHORs')
    });

モデルにバインドしようとしているものを正確に示すために、ビューから少しコードを投稿しました。

@model myModels.BOOK

@{
    ViewBag.Title = "Edit";
}

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Basic</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.TITLE)
        </div>
        <div class="editor-field" >
            @Html.EditorFor(model => model.TITLE)
            @Html.ValidationMessageFor(model => model.TITLE)
        </div>
    <div class="authors">
            <div class="editor-field">
                <input type="text" id="authors" name="authors" data-val="true"  data-val-required="You must enter at least one author" data-authors="@Json.Encode(Model.AUTHORs.Select(a => new { id = a.AUTHOR_ID, name = a.FULL_NAME }))"/>
                <span class="field-validation-valid" data-valmsg-for="authors" data-valmsg-replace="true"></span>
            </div>
        </div>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

フォームでモデルを更新しようとするときに([保存]を押した後)使用するコードは次のとおりです。

  [HttpPost]
        public ActionResult Edit(BOOK book)
        {
             if (ModelState.IsValid)
            {
                db.Entry(book).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Details", new { id = book.REF_ID });
            }
            ViewBag.REF_ID = new SelectList(db.REFERENCEs, "REF_ID", "REF_ID", book.REF_ID);
            return View(book);
        }

HTMLのコードを見ると、tokeninput要素から作成者をフォーマットしているように見えますが、このフォーマットには実際の問題があるようです。

<input type="text" id="AUTHORs" name="AUTHORs" data-val="true" data-val-required="You must enter at least one author" data-authors="

[{&quot;id&quot;:156787,&quot;name&quot;:&quot;Faure,M.&quot;},

{&quot;id&quot;:177433,&quot;name&quot;:&quot;Wang,D.Z.&quot;},

{&quot;id&quot;:177434,&quot;name&quot;:&quot;Shu,L.Sh&quot;},

{&quot;id&quot;:177435,&quot;name&quot;:&quot;Sheng,W.Z.&quot;}]"

style="display: none; ">
4

4 に答える 4

4

tokeninputプラグインを使用しているようです。これをASP.NETMVCで実装する方法について段階的な例を見てみましょう。

モデル:

public class Book
{
    public string Title { get; set; }
    public IEnumerable<Author> Authors { get; set; }
}

public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
}

コントローラ:

public class HomeController : Controller
{
    // fake a database. Obviously that in your actual application
    // this information will be coming from a database or something
    public readonly static Dictionary<int, string> Authors = new Dictionary<int, string>
    {
        { 1, "foo" },
        { 2, "bar" },
        { 3, "baz" },
        { 4, "bazinga" },
    };

    public ActionResult Index()
    {
        // preinitialize the model with some values => obviously in your
        // real application those will be coming from a database or something
        var model = new Book
        {
            Title = "some title",
            Authors = new[] 
            {
                new Author { Id = 2, Name = "bar" }
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(Book book)
    {
        return Content(string.Format("thanks for selecting authors: {0}", string.Join(" ", book.Authors.Select(x => x.Name))));
    }

    public ActionResult GetAuthors(string q)
    {
        var authors = Authors.Select(x => new
        {
            id = x.Key,
            name = x.Value
        });
        return Json(authors, JsonRequestBehavior.AllowGet);
    }
}

意見:

@model Book
@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.Title)
        @Html.EditorFor(x => x.Title)
    </div>
    <div>
        @Html.TextBoxFor(
            x => x.Authors, 
            new { 
                id = "authors", 
                data_url = Url.Action("GetAuthors", "Home"), 
                data_authors = Json.Encode(
                    Model.Authors.Select(
                        x => new { id = x.Id, name = x.Name }
                    )
                ) 
            }
        )
    </div>
    <button type="submit">OK</button>
}

<script type="text/javascript" src="@Url.Content("~/scripts/jquery.tokeninput.js")"></script>
<script type="text/javascript">
    var authors = $('#authors');
    authors.tokenInput(authors.data('url'), {
        hintText: 'Enter surname',
        searchingText: 'Searching...',
        preventDuplicates: true,
        allowCustomEntry: true,
        highlightDuplicates: false,
        tokenDelimiter: '*',
        resultsLimit: 10,
        theme: 'facebook',
        prePopulate: authors.data('authors')
    });
</script>

最後のステップは、IDから作成者を取得するカスタムモデルバインダーを作成することです。

public class AuthorModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var values = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (values != null)
        {
            // We have specified asterisk (*) as a token delimiter. So
            // the ids will be separated by *. For example "2*3*5"
            var ids = values.AttemptedValue.Split('*').Select(int.Parse);

            // Now that we have the selected ids we could fetch the corresponding
            // authors from our datasource
            var authors = HomeController.Authors.Where(x => ids.Contains(x.Key)).Select(x => new Author
            {
                Id = x.Key,
                Name = x.Value
            }).ToList();
            return authors;
        }
        return Enumerable.Empty<Author>();
    }
}

これはApplication_Startに登録されます:

ModelBinders.Binders.Add(typeof(IEnumerable<Author>), new AuthorModelBinder());
于 2012-09-24T10:57:52.517 に答える
0

私は小さなテストを行いました-そして、この種の属性テキストはエラーではなく、ブラウザによってJSONオブジェクトとして正しく認識されているようです

$("#authorlist").data("authors")ブラウザで監視する式を追加する か(F12キーを押す)、コンソールで実行してみてください。私にとっては、有効なjavascriptオブジェクトが返されます。

于 2012-09-24T11:06:16.433 に答える
0

シリアル化を使用できます

$("form").on('submit', function(event){
    event.preventDefault();
    var form = $(this);

    $.ajax({
       url: form.attr('action'),
       type: form.attr('method'),
       data: form.serialize(),
       success: function(r) { }
    });
});
于 2012-09-20T10:39:45.897 に答える
0

data-authors="@Json.Encode(Model.AUTHORs.Select(a => new { id = a.AUTHOR_ID, name = a.FULL_NAME }))「」

私はこれがすべきだと思います:

data-authors="@Html.Raw(Json.Encode(Model.AUTHORs.Select(a => new { id = a.AUTHOR_ID, name = a.FULL_NAME })))"
于 2012-09-24T10:54:19.273 に答える