Как применить проверку нокаута к свойствам каждого списка элементов, переданного MVC?

Ниже представлены модели представлений в ASP.NET MVC:

public class Email
{
  public string Selected { get; set; }
  public string Name { get; set; }
}
public class User
{
  public string UserName { get; set; }
  public IList<Email> Emails { get; set; }
}

Он передается в представление и выглядит следующим образом при определении модели нокаутирующего представления:

var viewModel = {
  UserName: ko.observable("@Model.UserName"),
  Emails: ko.observableArray(@Html.Json(@Model.Emails) || []),
  // many other things
}

Я хочу убедиться, что Email.Selected равно required. Как это сделать имея список, а не отдельные объекты. Я знаю, что это должен быть самый простой вопрос, но я не смог найти ничего по теме.

Я использую проверку нокаута на клиенте, так как Fluent и аннотация данных, к сожалению, не работают с нокаутом.


person Display Name    schedule 12.03.2013    source источник
comment
Вы хотите включить проверку на стороне клиента? Тип, используемый инфраструктурой MVC через jQuery?   -  person rae1    schedule 12.03.2013
comment
@ rae1n Хороший вопрос - я отредактирую свой вопрос. Аннотации данных и беглая проверка к сожалению не работают в контексте нокаута (научите меня иначе, если вы что-то знаете). Следовательно, я должен использовать проверку jQuery или Knockout. Я выбрал последнее. Я знаю, как выразить необходимое для одного элемента, но я получаю полный список с сервера - не знаю, как с этим справиться. Спасибо.   -  person Display Name    schedule 12.03.2013
comment
Причина, по которой я спрашиваю, заключается в том, что я видел предыдущий вопрос, в котором вы упомянули knockout-validation.js; однако я знаю только, как инициировать проверку массивов/списков с помощью проверки jQuery.   -  person rae1    schedule 12.03.2013
comment
Вы можете использовать Knockout custom validation (https://github.com/ericmbarnard/Knockout-Validation) для своих целей.   -  person Gaurav    schedule 12.03.2013


Ответы (1)


Как я упоминал в своем комментарии, пользовательская проверка нокаута может помочь, здесь я добавляю пример того, как использовать пользовательскую проверку нокаута в вашем случае:

var viewModel = {
  UserName: ko.observable("@Model.UserName"),
  Emails: ko.observableArray(@Html.Json(@Model.Emails) || []).
          extend({
             customRequired: { message: 'Selected is required' }
          });

  // many other things
}


ko.validation.rules['customRequired'] = {
    validator: function (emailList) {
        var pass = true;
        ko.utils.arrayFirst(emailList(), function(email){
           if(email.Selected == '')       //if Selected property is empty
           {
             pass = false;
             return true;                 //break the loop
           }
        });
       return pass;
    }
};
person Gaurav    schedule 12.03.2013
comment
Спасибо за комментарий (+1), спасибо за решение (будет). Я до сих пор не знаю, как выразить объект С# List<Email> внутри части комментария, которую вы оставили (поэтому я предоставил модель представления MVC для просмотра). Не могли бы вы получить доступ к свойству Selected внутри электронной почты в коде JS (извините, я относительно новичок) - поэтому и спрашиваю. Спасибо! - person Display Name; 12.03.2013
comment
Внутри пользовательского валидатора emailList будет observableArray, проверьте обновленный ответ - person Gaurav; 12.03.2013
comment
Это просто!? Большое спасибо, позвольте мне проверить, я вернусь. Я должен выучить java script однажды :) - person Display Name; 12.03.2013
comment
Насколько я понимаю, вы проверяете весь массив, чтобы Selected не был пустым. Я искал декларативно выразить, что г-н. Selected должен быть обязательным, что-то вроде Selected: ko.observable().extend({ required: true }) или что-то в этом роде... Подобно аннотациям данных в MVC. Это возможно? - person Display Name; 12.03.2013
comment
Selected should be required: true or smth like that.. под этим вы хотите сказать, что Selected должен быть истинным для всех объектов в массиве или хотя бы для 1? - person Gaurav; 12.03.2013
comment
Для всех. Весь смысл упражнения заключается в том, чтобы пользователь помечал каждое электронное письмо, которое он вводит, как домашнее/рабочее/личное и т. д. Поэтому, когда он отправляет, перед тем как перейти на сервер, на стороне клиента он будет иметь красный цвет вокруг каждой метки, которую он не выбрал, и сообщение об ошибке. Вместо функционального решения (зацикливания) я искал более элегантное, декларативно выражающее, что требуется, какая должна быть длина и т. д., вместо того, чтобы запускать какие-то функции. Надеюсь, вы следите за ... Спасибо - person Display Name; 12.03.2013
comment
Если я правильно понимаю, вам следует создать новый объект электронной почты в javascript, а ваша текущая модель представления содержит список объектов электронной почты (точно такая же структура, которая у вас есть на сервере). Затем вы можете применять правила к выбранным или другим свойствам в объекте электронной почты. - person Gaurav; 12.03.2013
comment
Я думаю, вы решили проблему с пользовательским валидатором. Что касается меня, то я перефразирую вопрос, потому что искал декларативное решение. Если вы знаете аннотации данных в ASP.NET MVC для каждого свойства, которое вы хотите проверить, вы определяете, какие проверки применяются, и сервер, и клиент проверяют его из коробки, просто нокаут выбивает его, и проверки больше не работают. Если бы это был не массив - это тривиально, расширьте каждое свойство и определите, что вы хотите, это массив, с которым я не знаю, как обращаться. Спасибо большое. - person Display Name; 12.03.2013