Knockout JS extender для проверки в сценарии master-detail

Моя веб-страница использует эту модель для сценария мастер-детали:

   ko.extenders.myrequired = function (target, overrideMessage) {
    //add some sub-observables to our observable
    target.hasError = ko.observable();
    target.validationMessage = ko.observable();

    //define a function to do validation
    function validate(newValue) {
        target.hasError(newValue ? false : true);
        target.validationMessage(newValue ? "" : overrideMessage || "This field is required");
    }

    //initial validation
    validate(target());

    //validate whenever the value changes
    target.subscribe(validate);

    //return the original observable
    return target;
};

function PluginViewModel() {
    var self = this;

    self.name = ko.observable();
    self.code = ko.observable();
}

function item() {
    var self = this;

    self.id = ko.observable();
    self.listIndex = ko.observable();
    self.value = ko.observable();
    self.label = ko.observable();
    self.tabPos = ko.observable();
    self.plugins = ko.observableArray();
};

function TableViewModel() {
    var self = this;

    self.id = ko.observable();
    self.name = ko.observable();
    self.viewName = ko.observable().extend({ myrequired: "Please enter a view name" });
    self.columns = ko.observableArray();
    self.filteredColumns = ko.observableArray();
}

function SchemaViewModel() {
    var self = this;

    self.name = ko.observable();
    self.tables = ko.observableArray();

    // Table selected in left panel
    self.selectedTable = ko.observable();
    self.selectTable = function (p) {
        self.selectedTable(p);
    }
}

Поэтому, когда я нажимаю "<" li ">" selectedTable ", привязка knockoutjs показывает мне другие поля, например, входной текст для записи поля viewName.

Это HTML код:

<div>
    <ul class="list" data-bind="foreach: tables">
        <li><a data-bind="text: name, click: $parent.selectTable"></a></li>
    </ul>
</div>
<div>
    <div id="editor-content">
        <section id="viewNameSection">
            <div data-bind="with: selectedTable">
                <label>View name: </label>
                <input id="txtViewName" class="inputs" data-bind="value: viewName, valueUpdate: 'input'" placeholder="eg. MyView" />
                <span data-bind="visible: viewName.hasError, text: viewName.validationMessage"></span>
            </div>
        </section>
    </div>
</div>

Проблема в том, что сообщение не отображается, даже если txtViewName пусто. Похоже, расширитель не проверка огня.

В чем я не прав?

РЕДАКТИРОВАТЬ: забавно то, что Jfiddle с тем же кодом копирования / вставки работает!

Я действительно не понимаю различий.

2 ответа

Решение

Я нашел свою ошибку. Поле 'viewName' не требует инициализации при заполнении таблиц. Итак, удаление

myTable.viewName("") 

оно работает.

Я считаю, что это должно быть

//define a function to do validation
function validate(newValue) {
    var isEmptyOrNull= typeof newValue === 'undefined' || !newvalue || newValue.length === 0;
    target.hasError(isEmptyOrNull);
    target.validationMessage( isEmptyOrNull ? 
                                overrideMessage || "This field is required"
                             :
                                "");
}

В качестве примечания вы можете рассмотреть вопрос о том, чтобы сделать validationMessage вычисленным значением вместо наблюдаемого.

Другие вопросы по тегам