Ненавязчивая проверка клиента при привязке шаблона нокаута

У меня есть модель с аннотациями данных, и я динамически связываю это с помощью viewmodel, использующего привязку шаблона к нокауту и ​​плагин отображения. Я пытаюсь сделать ненавязчивую проверку клиента для моей модели. Как мы можем это сделать в этом сценарии. Любая помощь/предложения?

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; }
    }

По моему мнению, я динамически привязываю список MyUser, используя ajax.

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>

Ответ 1

ответы pilavdzice и drogon неплохие, но мы забываем основную точку.

Поскольку мы используем шаблон MVVM для разделения пользовательского интерфейса и данных (+ vm), мы не хотим выполнять проверку UI, а DAL VALIDATION. Эти два совершенно разные, jquery validate - отличный плагин, но он проверяет UI (он начинается с пользовательского интерфейса, чтобы проверить поля).

Я нашел плагин проверки нокаута, который, кажется, делает все хорошо, и что он делает, это идти по противоположной дороге, он проверяет вашу модель просмотра, а не ваш пользовательский интерфейс (он фактически отображает элементы UI для отображения ошибок).

К сожалению, если ваша viewmodel становится сложной, у этого плагина возникнут проблемы, но в любом случае это путь.

Проверка подлинности UI прекрасна до тех пор, пока мы не используем шаблон MVVM, после чего мы разделяем компоненты (M-V-VM) для?

Надеюсь, я помог!

Спасибо!

Ответ 3

Я бы пошел с привязкой события jquery для этого.

Сначала добавьте свои атрибуты data-val к ​​входам, которые вы хотите проверить. (Чтобы выяснить, какие атрибуты data-val использовать, я обычно привязываю серверную сторону формы к модели и виду источника.)

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

Во-вторых, добавьте функцию утилиты проверки - это вызывает плагин проверки jquery, используемый MVC под обложками.

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

В-третьих, проверьте правильность запроса перед выдачей метода viewmodel. Обязательно удалите атрибут привязки "click" из разметки на вашей странице.

$('#..your form id...').live('submit', function (e) {
    e.preventDefault();
    if(validateForm($(this)))
        viewModel.saveUser();
});

Ответ 4

Если вы используете knockoutjs и jquery, я придумал следующий очень простой метод для базовой проверки.

Везде, где вы хотите отобразить сообщение об ошибке на своей странице, введите тег span следующим образом:

<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;
    }

Это намного проще и гибче, чем многие другие решения для проверки. Вы можете разместить сообщение об ошибке там, где хотите, и вам не нужно научиться пользоваться некоторой библиотекой проверки.