gpt4 book ai didi

c# - 具有 Asp.Net Core ViewComponents 的多个 Knockout View 模型

转载 作者:行者123 更新时间:2023-12-03 10:26:48 25 4
gpt4 key购买 nike

我有简单的FullName内部带有 knockout View 模型的 View 组件:

p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>

<p>Full name: <strong data-bind="text: fullName"></strong></p>

<script>
function AppViewModel() {
this.firstName = ko.observable("");
this.lastName = ko.observable("");

this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}

ko.applyBindings(new AppViewModel());
</script>

当我调用这个组件时,比如 @(await Component.InvokeAsync("FullName")) ,效果很好。

但是,当我尝试多次调用此组件时:
@(await Component.InvokeAsync("FullName"))
@(await Component.InvokeAsync("FullName"))
@(await Component.InvokeAsync("FullName"))
//etc...

我有一个错误,即 Knockout 无法应用多个相同的绑定(bind)。

那么,如何将多个带有 Knockout View 模型的 ViewComponents 包含在一个页面中?

最佳答案

在您的代码中,您正在调用 applyBindings每个您添加的组件一次,并且 Knockout 不会让您多次绑定(bind)某些内容,除非您首先删除绑定(bind)(根据 Matt.kaaj 的评论)。

话虽如此,我认为你应该看看 scoping your bindings如果您想在多个地方重用您的 View 模型。

全面披露 - 我对 asp.net 及其 ViewComponents 了解不多 ,如果语法不正确,请致歉,但它们似乎支持 passing in parameters .看起来您可以通过将组件定义更改为以下内容来解决此问题:

<div id=${idThatIPassIn}>
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>

<p>Full name: <strong data-bind="text: fullName"></strong></p>
</div>
<script>
function AppViewModel() {
this.firstName = ko.observable("");
this.lastName = ko.observable("");

this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}

ko.applyBindings(new AppViewModel(), document.getElementById('${idThatIPassIn}'));
</script>

然后初始化:
@(await Component.InvokeAsync("FullName"), new { idThatIPassIn = "name-1" })
@(await Component.InvokeAsync("FullName"), new { idThatIPassIn = "name-2" })
@(await Component.InvokeAsync("FullName"), new { idThatIPassIn = "name-3" })

这样,每次你告诉 knockout 应用绑定(bind)时,绑定(bind)都会被上下文化为一个包装你的 <p> 的 div。元素,所以你最终不会试图重新绑定(bind)已经绑定(bind)的东西。

或者,您可以分配一个随机的任意 ID 并绑定(bind)到该 ID,而不是传入一个 ID。在任何一种情况下,将您的 applyBindings 调用范围限定为一个元素。

编辑 - 你提到不想通过 ID 绑定(bind)。而是尝试使用一个类和 jQuery's .each方法。就像是:
<div class="name-block">
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>

<p>Full name: <strong data-bind="text: fullName"></strong></p>
</div>

按照您当前的方式进行初始化:
@(await Component.InvokeAsync("FullName"))
@(await Component.InvokeAsync("FullName"))
@(await Component.InvokeAsync("FullName"))

然后在另一个单独的 .js 包含中,添加:
<script>
//I'm assuming that jQuery is available
$(document).ready(function(){

function AppViewModel() {
this.firstName = ko.observable("");
this.lastName = ko.observable("");

this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}


$(".name-block").each(function(index, obj){
ko.applyBindings(new AppViewModel(), obj);
});
});
</script>

这样,您的 View 模型只定义一次,并且您的绑定(bind)适用于具有“名称 block ”类的每个单独的 div。

我还将整个过程包装在 jQuery 的 document ready 中。函数,因此您可以放心地假设 DOM 已准备好进行操作。只需确保您的脚本也包含在您的页面中,因为现在它已与 View 组件分开。

关于c# - 具有 Asp.Net Core ViewComponents 的多个 Knockout View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39920751/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com