我解释一下这个问题有点复杂。 基本上我有一个viewmodel,我绑定到一个视图,在该viewmodel中我有一个可观察的对象,我绑定到视图与来自knockout的“with”标签。 此属性称为SelectedItem,因为它表示您从网格中选择的项目。此网格中的数据是普通对象,因此我必须转换为obervable对象,以便将其绑定到此视图。
当我必须绑定第二个对象时,问题就出现了,应用程序就不起作用了。
我为这个问题创造了一个小提琴。 http://jsfiddle.net/q7q0f7oq/11/
Natal.applyBindings(myViewModel).done(function() {
Natal.Validation.init('#editForm');
});
这是我在工作中使用的库,它封装了Knockoutjs和其他库。
如果你按下新按钮,然后按下保存按钮(没有完成任何操作),它将触发验证。然后用取消按钮关闭窗口,再次打开窗口,再次按下新按钮。 当您尝试再次执行验证时,它将失败。
现在,我发现这不是与Knockout进行此绑定的正确方法,但我不知道我该怎么做才能解决这个问题。 唯一能解决这个问题的方法就是回收对象,不要创建新对象。
答案 0 :(得分:1)
看起来你不熟悉Knockout的工作方式。你不能以你的方式混合jQuery和Knockout并获得好的结果。 Knockout方法是您从viewmodel控制视图。你不能直接到达并直接摆弄DOM。如果您觉得必须摆弄DOM,请问自己"为什么我不通过模型这样做?"
Natal的验证看起来对Knockout不友好,因为它显然想直接在DOM上工作。你无能为力。
我找到了一个用于Bootstrap模式的bindingHandler供你使用,所以它现在由modalIsOpen
可观察的控制。我创建了observable来绑定其他表单输入。我将验证和重置函数放在viewmodel中,而不是让它们是全局的。我使用绑定来挂钩点击事件。
每次重置表单时,为codigo
创建一个新的observable似乎没有意义;相反,我只是改变了它的价值。也许这有所不同。我不知道。现在运行验证没有问题。
ko.bindingHandlers.modal = {
init: function(element, valueAccessor) {
$(element).modal({
show: false
});
var value = valueAccessor();
if (ko.isObservable(value)) {
$(element).on('hide.bs.modal', function() {
value(false);
});
}
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).modal("destroy");
});
},
update: function(element, valueAccessor) {
var value = valueAccessor();
if (ko.utils.unwrapObservable(value)) {
$(element).modal('show');
} else {
$(element).modal('hide');
}
}
};
$(document).ready(function() {
// Cuando se oculta el modal, reseteo la validación para que cuando vuelva a abrir no esten las marcas de validación
// Definimos el viewmodel del ejemplo
var ViewModel = function() {
var self = this;
var form = "#editForm";
function resetForm() {
Natal.Validation.reset(form);
var item = self.selectedItem();
item.codigo(0);
item.descripcion('');
item.comments('');
}
self.modalIsOpen = ko.observable(false);
self.openModal = function() {
self.modalIsOpen(true);
};
self.closeModal = function() {
self.modalIsOpen(false);
resetForm();
};
self.validar = function(data, event) {
if (Natal.Validation.validate(form)) {
console.log('validacion true');
} else {
console.log('validacion false');
}
};
self.selectedItem = Natal.observable({
codigo: Natal.observable(12345),
descripcion: Natal.observable('Whatever'),
comments: Natal.observable('')
});
};
var myViewModel = new ViewModel();
Natal.applyBindings(myViewModel).done(function() {
Natal.Validation.init('#editForm');
});
});

<script src="https://natalfwk.gruposancorseguros.com/1.4.6/natal.min.js"></script>
<link href="https://natalfwk.gruposancorseguros.com/1.4.6/natal.min.css" rel="stylesheet" />
<div id="myToolbar">
<button class="btn btn-primary" data-toggle="modal" data-bind="click:openModal">New</button>
</div>
<div id="modalNuevo" data-bind="modal:modalIsOpen" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-scrollable">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span>
</button>
<h4 class="modal-title">Generic Title</h4>
</div>
<div class="modal-body">
<form id="editForm" class="">
<div class="form-body" data-bind="with: selectedItem">
<div class="row">
<div class="form-group col-md-3">
<label for="inCodigo" class="control-label">Code</label>
<input type="text" class="form-control" id="inCodigo" name="inCodigo" data-bv-notempty="true" data-inputmask="'alias': 'integer'" data-bind="value: codigo" />
</div>
</div>
<div class="row">
<div class="form-group col-md-6">
<label for="inDescripcion" class="control-label">Description</label>
<input type="text" class="form-control" id="inDescripcion" name="inDescripcion" data-bv-notempty="true" data-bind="value: descripcion" />
</div>
</div>
<div class="row">
<div class="form-group col-md-6">
<label for="description" class="control-label">Comments</label>
<textarea class="form-control" cols="20" id="textArea" rows="3"></textarea>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button nf-btn-guardar-registro type="button" class="btn btn-primary" data-bind="click:validar">Save</button>
<button nf-btn-cancelar-modal type="button" class="btn btn-link" data-bind="click: closeModal">Cancel</button>
</div>
</div>
</div>
</div>
&#13;