我有自己的淘汰赛组件:
ko.components.register("library-link-form",
{
viewmodel: LibraryLinkViewModel,
template: { controller: "PartialViews", action: "LibraryLinkPartial" }
//This is custom template loader, which loads asp.net partial view from controller via ajax request.
});
我的
LibraryLinkViewModel.js
:function LibraryLinkViewModel() {
var self = this;
self.OtherLibrary = ko.observable("");
self.Type = ko.observable("");
}
局部视图
_LibraryLinkForm
:@{
var libraryDropdownId = $"dropdown-{Guid.NewGuid().ToString().Substring(0, 8)}";
var typeDropdownId = $"dropdown-{Guid.NewGuid().ToString().Substring(0, 8)}";
var scriptId = $"script-{Guid.NewGuid().ToString().Substring(0, 8)}";
var contextId = $"context-{Guid.NewGuid().ToString().Substring(0, 8)}";
var librariesList = //some list with predefined libraries
var typeList = // some list with predefined library's types
}
<!-- ko template: { afterRender: function()
{
eval($('#@scriptId').html());
}
}
-->
<!-- /ko -->
<div id ="@contextId">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-body">
<div class="col-md-12">
<div class="row">
<form class="form-horizontal">
<div class="form-group">
<div class="col-md-6">
@(Html.Kendo().DropDownList()
.Name(libraryDropdownId)
.DataValueField("Value").DataTextField("Text")
.HtmlAttributes(new
{
style = "width: 100%",
data_bind = "value: OtherLibrary"
}).BindTo(librariesList).Deferred()
)
</div>
<div class="col-md-4">
@(Html.Kendo().DropDownList()
.Name(typeDropdownId)
.DataValueField("Value").DataTextField("Text")
.HtmlAttributes(new
{
style = "width: 100%",
data_bind = "value: Type"
}).BindTo(typeList).Deferred()
)
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<deferred-script class="hidden" id="@scriptId">
@(Html.Kendo().DeferredScripts(false))
</deferred-script>
</div>
最后,我如何结合所有这些:
<button type="button" data-bind="click: addLibraryLink"></button>
<ul class="list-unstyled" data-bind="foreach: LibraryLinks">
<li><library-link-form></library-link-form></li>
</ul>
<script type="text/javascript">
function LibraryViewModel() {
var self = this;
self.LibraryLinks = ko.observableArray();
self.addLibraryLink = function () {
ko.components.clearCachedDefinition();
self.LibraryLinks.push(new LibraryLinkViewModel());
};
}
ko.applyBindings(new LibraryViewModel());
</script>
我正在使用Knockout v.3.4,Asp.Net Core v.1.0.0。
因此,问题在于,当我尝试将新的库链接添加到列表时,敲除绑定根本无法正常工作,可能是因为错误:
未捕获ReferenceError:无法处理绑定“值:功能
(){return OtherLibrary}“消息:未定义OtherLibrary
我应该怎么处理这个错误?如何正确将淘汰赛的组件添加到列表中?
最佳答案
答案很简单。让我们看一下示例,并检查其中的上下文:
<div data-bind="foreach: LibraryLinks"> // here we have LibraryViewModel context
<library-link-form> // here we have LibraryLinkViewModel context
//inside component we have THIRD context, which is empty!
</library-link-form>
</div>
因此,问题在于,
data_bind = "value: OtherLibrary"
中的OtherLibrary引用了第三个上下文,该上下文为空且未定义。只需调用父母的上下文即可解决问题。
例如:
data_bind = "value: $parent.OtherLibrary"