Knockout.js 可观测阵列中的可观测视图模型don';我不能在淘汰赛中工作
我有一个简单的HTML标记,其中包含我的视图模型列表和模板。此外,我的viewmodel位于Knockout.js 可观测阵列中的可观测视图模型don';我不能在淘汰赛中工作,knockout.js,viewmodel,observable,Knockout.js,Viewmodel,Observable,我有一个简单的HTML标记,其中包含我的视图模型列表和模板。此外,我的viewmodel位于部分: <div class="container"> <div class="row"> <div class="col-md-6"> <div class="col-md-12"> <div class="panel panel-primary"> <div class="pa
部分:
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">
Names
<button type="button" class="btn btn-link" data-bind="click: addName">
<span class="glyphicon glyphicon-plus"></span>
</button>
</div>
<div class="panel-body">
<ul class="list-group" id="namesList" data-bind="foreach: Names">
<li class="list-group-item"><my-comp></my-comp></li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="col-md-12">
<pre data-bind="text: ko.toJSON(Names, null, 2)"></pre>
</div>
</div>
</div>
</div>
<script type="text/html" id="fullNameTmpl">
<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="textInput: firstName" /></p>
<p>Last name: <input data-bind="textInput: lastName" /></p>
<p>Full name: <input data-bind="textInput: fullName"></p>
<button data-bind="click: capitalizeLastName">Go caps</button>
</script>
<script>
function AppViewModel() {
var self = this;
self.firstName = ko.observable("Bert");
self.lastName = ko.observable("Bertington");
this.fullName = ko.pureComputed({
read: function () {
return self.firstName() + " " + self.lastName();
},
write: function (value) {
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) {
self.firstName(value.substring(0, lastSpacePos));
self.lastName(value.substring(lastSpacePos + 1));
}
},
owner: self
});
self.capitalizeLastName = function () {
var currentVal = this.lastName();
this.lastName(currentVal.toUpperCase());
};
}
ko.components.register('my-comp', {
viewModel: AppViewModel,
template: { element: "fullNameTmpl" }
});
function NamesViewModel() {
var self = this;
self.Names = ko.observableArray();
self.addName = function () {
var vm = ko.observable(new AppViewModel());
self.Names.push(vm);
}
}
ko.applyBindings(new NamesViewModel());
</script>
名字
名字:
姓氏:
名字:
姓氏:
全名:
盖帽
函数AppViewModel(){
var self=这个;
self.firstName=ko.可观察(“伯特”);
self.lastName=ko.observable(“伯丁顿”);
this.fullName=ko.pureComputed({
读:函数(){
返回self.firstName()+“”+self.lastName();
},
写入:函数(值){
var lastSpacePos=value.lastIndexOf(“”);
如果(lastSpacePos>0){
self.firstName(value.substring(0,lastSpacePos));
self.lastName(value.substring(lastSpacePos+1));
}
},
所有者:self
});
self.capitalLastName=函数(){
var currentVal=this.lastName();
this.lastName(currentVal.toUpperCase());
};
}
ko.组件寄存器('my-comp'{
viewModel:AppViewModel,
模板:{element:“fullNameTmpl”}
});
函数名称ViewModel(){
var self=这个;
self.Names=ko.observearray();
self.addName=函数(){
var vm=ko.observable(新的AppViewModel());
self.Names.push(vm);
}
}
applyBindings(新名称视图模型());
它工作得很好,我可以添加一个项目到列表中,这些项目中的数据绑定也可以工作。当我添加新的AppViewModel
时,我可以在
部分的Names
数组中看到它。问题是,当我在嵌套的viewmodel中更改某些值时,比如键入新的姓氏,不管怎样,在名称数组中当前viewmodel的
部分中没有任何更改
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">
Names
<button type="button" class="btn btn-link" data-bind="click: addName">
<span class="glyphicon glyphicon-plus"></span>
</button>
</div>
<div class="panel-body">
<ul class="list-group" id="namesList" data-bind="foreach: Names">
<li class="list-group-item"><my-comp></my-comp></li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="col-md-12">
<pre data-bind="text: ko.toJSON(Names, null, 2)"></pre>
</div>
</div>
</div>
</div>
<script type="text/html" id="fullNameTmpl">
<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="textInput: firstName" /></p>
<p>Last name: <input data-bind="textInput: lastName" /></p>
<p>Full name: <input data-bind="textInput: fullName"></p>
<button data-bind="click: capitalizeLastName">Go caps</button>
</script>
<script>
function AppViewModel() {
var self = this;
self.firstName = ko.observable("Bert");
self.lastName = ko.observable("Bertington");
this.fullName = ko.pureComputed({
read: function () {
return self.firstName() + " " + self.lastName();
},
write: function (value) {
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) {
self.firstName(value.substring(0, lastSpacePos));
self.lastName(value.substring(lastSpacePos + 1));
}
},
owner: self
});
self.capitalizeLastName = function () {
var currentVal = this.lastName();
this.lastName(currentVal.toUpperCase());
};
}
ko.components.register('my-comp', {
viewModel: AppViewModel,
template: { element: "fullNameTmpl" }
});
function NamesViewModel() {
var self = this;
self.Names = ko.observableArray();
self.addName = function () {
var vm = ko.observable(new AppViewModel());
self.Names.push(vm);
}
}
ko.applyBindings(new NamesViewModel());
</script>
我怎样才能制作出一个真正可观测的阵列?添加这样的组件最有利可图的方法是什么?我已经完成了嵌套viewmodel observable,但它似乎不起作用。您的代码中有几个问题。问题不一定与可观测阵列有关,而是与组件的使用有关。列出了组件的用途。需要注意的一些事项:
可观察的数组元素不需要设置为可观察的。因此无需执行var vm=ko.observable(新的AppViewModel())代码>只需使用var vm=new-AppViewModel()编码>并推到阵列上。但是,如果您想使用组件,那么这也不正确!我们正在做的基本上是两次更新AppViewModels!你知道为什么吗?在上面的行中显式执行一次,然后组件隐式执行一次。每次创建组件时,它都与AppViewModel关联—这就是注册组件时发生的情况李>
组件与关联您可以将其视为一个具有自己属性、功能、计算结果等的迷你viewModel。因此,在您的情况下,您可能不需要使用组件->复制并将
标记的内部内容粘贴到
中,它应该可以正常工作
我不确定这是否是你想要的答案,但这应该是你想要的。如果您愿意,您可以使用组件,但您必须进行更多的更改,并具有一点点不必要的复杂性。我擅自更改了变量名。我认为这样可能更合适。希望这有帮助
编辑
我已经编辑了代码片段以使用组件。这个具体实现的问题在于,组件现在通过名称observableArray与AppViewModel
紧密耦合。在您的情况下,这可能没有问题,但通常会导致不希望的行为,尤其是当视图模型开始变得更大、更复杂时。当然,为了更好地解耦,您可以传入firstName
和lastName
的未包装值,但随后您将回到原点,因为
不会注册对名称所做的任何更改
ko.components.register('my-comp'){
viewModel:函数(参数){
var self=这个;
self.firstName=params.data.firstName
self.lastName=params.data.lastName
self.fullName=ko.pureComputed({
读:函数(){
返回self.firstName()+“”+self.lastName();
},
写入:函数(值){
var lastSpacePos=value.lastIndexOf(“”);
如果(lastSpacePos>0){
self.firstName(value.substring(0,lastSpacePos));
self.lastName(value.substring(lastSpacePos+1));
}
},
所有者:self
});
self.capitalLastName=函数(){
var str=self.lastName();
self.lastName(str.toUpperCase());
};
},
模板:{
元素:“fullNameTmpl”
}
});
var Name=function(){
this.firstName=ko.可观察(“伯特”);
this.lastName=ko.observable(“麦克伯丁顿”);
}
函数AppViewModel(){
var self=这个;
self.names=ko.observearray();
self.addName=函数(){
self.names.push(新名称());
}
}
应用绑定(新的AppViewModel())代码>
名字
加上花花公子
名字:
姓氏:
名字:
姓氏:
全名:
盖帽
我认为