При использовании свойства knockout.validation свойство isValid будет неверно сообщать о своем статусе, но только когда оно «внутри» ko.foreach.При использовании проверки нокаута isValid сообщения некорректно при привязке внутри ko.foreach
Используя фрагмент кода ниже, если вы запустите и введите следующие значения (д, г, 10) в том же текстовом поле, вы получите следующий результат:
- self.InvoiceAmount является д и сам .InvoiceAmount.isValid верно
- self.InvoiceAmount является г и self.InvoiceAmount.isValid ложно
- self.InvoiceAmount 10 и self.InvoiceAmount.isValid ложна
Как вы можете видеть, v правило alidation для числа и q не должно сообщать об истинности, а также 10 не должны сообщать об ошибке.
Похоже, что исполнение выполнено, потому что InvoiceAmount.subcribe выполняется до InvoiceAmount.isValid.subscribe.
Когда вид модели просто простое свойство, результаты, как и ожидалось:
- self.item является д и self.item.isValid ложно
- self.item является г и я. item.isValid ложна
- self.item 10 и self.item.isValid верно
Кто знает, почему это может происходить?
< Редактировать >
Я очень плохо задавая правильный вопрос, так что я постараюсь сделать его немного более ясно, что я после. К сожалению;)
мне нужно знать, если значение входного сигнала является действительным, если внутри функцией «подписаться» из наблюдаемых, который связан с этим входом.
Я использую значение isValid внутри функцию подписки, чтобы определить, может ли выполнение продолжить (isValid is true) или если выполнение должно прекратиться (isValid is false).
Когда вход связан с наблюдаемым внутри ko.foreach, значение isValid не обновляется до ПОСЛЕ выполняется функция подписки наблюдаемого. Это означает, что я получаю устаревшее значение для isValid, когда мне нужно решить, может ли выполнение продолжить или если выполнение должно прекратиться.
</Edit >
ko.bindingHandlers.numeral = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = ko.utils.unwrapObservable(valueAccessor()),
format = ko.utils.unwrapObservable(allBindingsAccessor().format) || ko.bindingHandlers.numeral.defaultFormat,
formattedValue = Number(value) ? numeral(value).format(format) : value;
$(element).val(formattedValue);
},
defaultFormat: "0,0.00"
};
var viewModel = function(param) {
var self = this;
self.item = ko.observable().extend({ number: true });
self.item.subscribe(function(value) {
$("#log").append("<p>self.item is " + value + " and self.item.isValid is " + self.item.isValid() + "</p>");
});
self.items = ko.mapping.fromJS([]);
ko.mapping.fromJS(param, {
key: function(data) {
return data.CustomerId;
},
create: function(options) {
return new itemViewModel(options.data);
}
}, self.items);
};
var itemViewModel = function(item) {
var self = this;
ko.mapping.fromJS(item, {}, self);
self.InvoiceAmount.extend({ number: true });
self.InvoiceAmount.subscribe(function(value) {
$("#log").append("<p>self.InvoiceAmount is " + value + " and self.InvoiceAmount.isValid is " + self.InvoiceAmount.isValid() + "</p>");
});
}
$(function() {
var vm = new viewModel([{ "InvoiceAmount": 10 }, { "InvoiceAmount": 20 }, { "InvoiceAmount": 30 }, { "InvoiceAmount": 40 }]);
ko.applyBindings(vm);
});
.error {
color: #FF0000;
}
p {
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/numeral.js/1.5.3/numeral.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.js"></script>
<div>
single item:<br/>
<input type="text" data-bind="numeral: item"/>
</div>
<div>
foreach:<br/>
<table>
<tbody data-bind="foreach: items">
<tr>
<td><input type="text" data-bind="numeral: InvoiceAmount"/></td>
</tr>
</tbody>
</table>
</div>
<div id="log"></div>
я вижу что-то странное с числовым bindingHandlers я пытался модифицировать с помощью 'autoNumeric', которые я знаю о его проверить здесь http://jsfiddle.net/LkqTU/27291/. вы можете направить свой ответ на автономию здесь http://stackoverflow.com/questions/27369871/knockoutjs-intercept-to-one-decimal-place/27372190#27372190 –
Не глядя дальше, я предполагаю, что вы можете использовать '.extend ({notify: always})' KO extender. Это гарантирует, что ваши подписчики будут уведомлены каждый раз, когда доступ к значению будет достигнут, даже если он останется прежним. – Tyblitz