10

私はデータ注釈付きのモデルを持っており、ノックアウト テンプレート バインディングとマッピング プラグインを使用してビューモデルと動的にバインディングしています。私は自分のモデルで目立たないクライアント検証を実行しようとしています。このシナリオでそれを行う方法。ヘルプ/提案はありますか?

public class MyUser
    {
        [Required]
        [StringLength(35)]
        public string Username { get; set; }

        [Required]
        [StringLength(35)]
        public string Forename { get; set; }

        [Required]
        [StringLength(35)]
        public string Surname { get; set; }
    }

私の見解では、ajax を使用して MyUser のリストを動的にテンプレート バインドしています。

public JsonResult TestKnockout()
        {
            IList<MyUser> myUserList = new List<MyUser>();
            myUserList.Add(new MyUser { Username = "ajohn", Surname = "surname" });
            myUserList.Add(new MyUser { Username = "ajohn1", Surname = "surname1" });

            return Json(myUserList, JsonRequestBehavior.AllowGet);
        }
    }

意見:

<form id="Userform" action='@Url.Action("Save", "Home")' data-bind="template: {name: 'UserTemplate', foreach:UserList}">
<input type="Submit" name="name" value="Submit" />
</form>
<script id="UserTemplate" type="text/Html">
 <input type="text" data-bind="value: Username"></input>
 <input type="text" data-bind="value: Forename"></input>
 <input type="text" data-bind="value: Surname"></input> 
</script>
<script type="text/javascript">


    var viewModel = {
        UserList: ko.observableArray(new Array()),

        Save: function () {          
            //// reached here means validation is done.
            alert("Save");
        }
    }
    ko.applyBindings(viewModel);


    $.ajax({
        type: 'GET',
        url: '../Home/TestKnockout',
        contentType: "application/json",
        success: function (data) {
            $.each(ko.mapping.fromJS(data)(), function () {
                viewModel.UserList.push(this);
            })

            // attach the jquery unobtrusive validator
            $.validator.unobtrusive.parse("#Userform");

            // bind the submit handler to unobtrusive validation.
            $("#Userform").data("validator").settings.submitHandler = viewModel.Save;
        },
        error: function (xhr, ajaxOptions, thrownError) {
            alert(xhr.status);
            alert(thrownError);
        }
    });

</script>
4

4 に答える 4

11

pilavdzice と drogon の回答は非常に優れていますが、基本的な点を忘れています。

UI とデータ (+vm) の分離に MVVM パターンを使用しているため、UI の検証ではなく、データの検証を実行します。これら 2 つはまったく異なります。jquery validate は優れたプラグインですが、UI 検証を行います (フィールドをチェックするために UI から開始します)。

非常にうまく機能しているように見えるノックアウト検証プラグインを見つけましたが、それは反対の道を行くことであり、UI ではなくビューモデルを検証します (実際には UI 要素にマップしてエラーを表示します)。

残念ながら、ビューモデルが複雑になると、そのプラグインにはいくつかの問題が発生しますが、いずれにせよこれが進むべき道です。

MVVM パターンを使用しない限り、UI 検証は完璧です。結局のところ、何のためにコンポーネント (MV-VM) を分離するのでしょうか?

私が助けてくれることを願っています!

ありがとう!

于 2012-04-21T09:57:49.960 に答える
4

私はあなたと同じ問題を抱えていたので、次のコンポーネントを書きました。

https://www.nuget.org/packages/ScriptAnnotations/

https://scriptannotations.codeplex.com/

これが役立つかどうか教えてください。

于 2014-04-19T02:49:50.840 に答える
2

ノックアウト js と jquery を使用している場合は、基本的な検証を行うための次の非常に単純な方法を思い付きました。

ページ上のエラー メッセージを表示する場所には、次のようなスパン タグを含めます。

<span name="validationError" style="color:Red" 
data-bind="visible: yourValidationFunction(FieldNameToValidate())">
* Required.
</span>

明らかに、やりたいことを何でも実行するには、「yourValidationFunction」を記述する必要があります。true または false を返す必要があるだけです。true はエラーを表示することを意味します。

jquery を使用して、検証エラーが表示された場合にユーザーが続行できないようにすることができます。おそらく、javascript関数をトリガーしてajaxなどを実行する保存ボタンがすでにあるので、これを一番上に含めてください。

 if ($("[name='validationError']:visible").length > 0) {
        alert('Please correct all errors before continuing.');
        return;
    }

これは、他の多くの検証ソリューションよりもはるかにシンプルで柔軟です。エラー メッセージは好きな場所に配置でき、検証ライブラリの使い方を学ぶ必要はありません。

于 2012-03-09T20:33:22.543 に答える
2

これにはjqueryのイベントバインディングを使用します。

まず、検証する入力に data-val 属性を追加します。(どの data-val 属性を使用するかを判断するために、私は通常、サーバー側のフォームをモデルにバインドし、ソースを表示します。)

     <input data-val-required="test" data-val="true" data-bind="visible: 
     $parent.userEditMode, value: FirstName" />

次に、検証ユーティリティ関数を追加します。これは、MVC が内部で使用する jquery 検証プラグインを呼び出します。

    function validateForm(thisForm) {
        var val = thisForm.validate();
        var isValid = val.form();
        alert(isValid);
        if (!isValid) {
            thisForm.find('.input-validation-error').first().focus();
        }
        return isValid;
    }

3 番目に、viewmodel メソッドを発行する前に validate を呼び出します。ページのマークアップから「クリック」データバインド属性を必ず削除してください。

$('#..your form id...').live('submit', function (e) {
    e.preventDefault();
    if(validateForm($(this)))
        viewModel.saveUser();
});
于 2012-02-07T15:49:46.240 に答える