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 вычисленным значением вместо наблюдаемого.