如何从另一个视图模型访问 select 选项可观察到 selected 值?
How to access a select option observable for selected value from another view model?
我有两个视图模型,一个包含一个 observable
,它接收来自 select option
的 selectedValue。
如何从另一个视图模型访问所选值,在本例中为 selecteArtist()
?每次更改值时,我都需要将其作为参数传递给 ViewModelB。
ViewModel A:
function ViewModelA(){
var self = this;
// Access this from outside
self.selectedArtist = ko.observable();
var data = [{
"ArtistId": "1",
"LastName": "Secada",
"FirstName": "Jon"
},
{
"ArtistId": "2",
"LastName": "Dion",
"FirstName": "Celine"
}];
self.artists = ko.computed(function () {
return ko.utils.arrayMap(data,
function (artist) {
return {
fullName: artist.FirstName + ' ' + artist.LastName,
value: artist.ArtistId
}
});
});
}
ViewModel B:
function ViewModelB(){
var self = this;
// Something like this:
var viewModelA = new ViewModelA();
self.selArtist = ko.observable(viewModelA.selectedArtist().value);
}
我试图做这样的事情:
self.selArtist = ko.computed(function () {
if(self.selectedArtist()){
return self.selectedArtist().ArtistId;
}
});
然后这样访问:
var viewModelA = new ViewModelA();
viewModelA.selArtist();
结果:undefined:
更新:
根据下面的评论,我稍微更改了代码,但我仍然无法从 viewModelA 访问选定的值。
例如这个有效:
self.firstName = ko.observable('Bob');
self.lastName = ko.observable('Smith');
self.fullName = ko.computed(function() {
return self.firstName() + " " + self.lastName();
});
这样调用:
var viewModelB = function(vma){
var self = this;
// Alert for example:
alert(vma.fullName());
};
var viewModelMain = (function(){
var self = this;
self.viewModelA = new viewModelA();
self.viewModelB = new viewModelB(self.viewModelA);
})();
如果我尝试调用 self.selectedArtist().value
它不会像上面所说的那样工作。
我问过a similar question on CodeReview。基本上,有三个选项:
- 将 parent 传递给 child 并在 child 视图模型中放置逻辑;
- 让parent处理children的一切;
- 创建管理服务/object 来处理这些事情。
我发现第三个选项在 Knockout 中表现不佳,但请注意,这主要是个人意见。
我发现当 child class 非常小 and/or 视图模型树中的叶节点时,第二个选项很有用。
我发现我通常最终会使用第一个选项。使用您提供给我们的代码,这对您来说也是最有意义的。例如:
function ViewModelB(parent){
var self = this;
self.selArtist = ko.computed(function () {
if(!!parent.selectedArtist()){
return parent.selectedArtist().id;
}
return undefined;
});
}
function ArtistVm(data) {
var self = this;
self.id = data.ArtistId;
self.firstName = ko.observable(data.FirstName);
self.lastName = ko.observable(data.LastName);
self.fullName = ko.pureComputed(function() {
return self.firstName() + ' ' + self.lastName();
});
}
function ViewModelA(){
var self = this;
self.selectedArtist = ko.observable(null);
self.artists = ko.observableArray(ko.utils.arrayMap(data,
function (artist) {
return new ArtistVm(artist);
});
});
self.viewModelB = ko.observable(new ViewModelB(self));
}
更新:工作解决方案:
你想做什么?
我需要将视图模型分解成更小的功能部分,以便将每个主要功能划分为它自己的功能(视图模型)。
你遇到了什么问题?
该应用程序包含一个 Select Option Binding
,我需要从另一个视图模型访问所选值,以便我可以使用该值作为参数来使用不同的视图模型执行其他绑定。
但是,我无法访问Selected Value
,当我终于解决了这个问题时,又出现了另一个问题,这次Select Options Binding
如果之前有任何依赖绑定将无法工作。
因为我使用选定值作为参数,如果使用参数的任何依赖绑定被放置在 select 选项 HTML 之上,代码将无法运行。 select 选项必须放在第一位:
解法:
HTML:
<!-- Binding with View Model B -->
<div id="artist-detail" data-bind="with: ArtistBio()[0]">
<p data-bind="text: ArtistId"></p>
<p data-bind="text: Bio"></p>
</div>
<!-- Binding with View Model A -->
<div id="artist-list">
<select data-bind="options: Artists,
optionsText: 'FullName', value: SelectedArtist"></select>
</div>
查看模型A:
function ViewModelA(){
var self = this;
self.SelectedArtist = ko.observable();
var artistList = [{
"ArtistId": "1",
"LastName": "Secada",
"FirstName": "Jon"
},
{
"ArtistId": "2",
"LastName": "Dion",
"FirstName": "Celine"
}];
self.Artists = ko.computed(function () {
return ko.utils.arrayMap(artistList,
function (artist) {
return {
FullName: artist.FirstName + ' ' + artist.LastName,
value: artist.ArtistId
}
});
});
}
查看模型 B:
function ViewModelB(vma){
var self = this;
var artistDetail = [{
"ArtistId": "1",
"Bio": "Jon Secada is a Cuban American singer and songwriter. " +
"Secada was born in Havana, Cuba, and raised in Hialeah, Florida. " +
"He has won two Grammy Awards and sold 20 million albums since his " +
"English-language debut album in 1992"
},
{
"ArtistId": "2",
"Bio": "Céline Marie Claudette Dion, CC OQ ChLD is a Canadian " +
"singer, songwriter, businesswoman and occasional actress."
}];
self.ArtistBio = ko.computed(function () {
if(vma.SelectedArtist()){
return ko.utils.arrayFilter(artistDetail, function (item) {
// Access the selected value here and return matching actist
return item.ArtistId === vma.SelectedArtist().value;
});
}
});
}
执行两个视图模型的绑定:
var viewModelA = new ViewModelA();
var viewModelB = new ViewModelB(viewModelA);
ko.applyBindings(viewModelA, document.getElementById('artist-list'));
ko.applyBindings(viewModelB, document.getElementById('artist-detail'));
使用此代码,我将 select 列表放在哪里并不重要,因为我首先调用并绑定到视图模型 A。
这是我学习的第四周KnockoutJS
所以请随时改进答案。
这是一个带有工作示例的 JSFiddle:
我有两个视图模型,一个包含一个 observable
,它接收来自 select option
的 selectedValue。
如何从另一个视图模型访问所选值,在本例中为 selecteArtist()
?每次更改值时,我都需要将其作为参数传递给 ViewModelB。
ViewModel A:
function ViewModelA(){
var self = this;
// Access this from outside
self.selectedArtist = ko.observable();
var data = [{
"ArtistId": "1",
"LastName": "Secada",
"FirstName": "Jon"
},
{
"ArtistId": "2",
"LastName": "Dion",
"FirstName": "Celine"
}];
self.artists = ko.computed(function () {
return ko.utils.arrayMap(data,
function (artist) {
return {
fullName: artist.FirstName + ' ' + artist.LastName,
value: artist.ArtistId
}
});
});
}
ViewModel B:
function ViewModelB(){
var self = this;
// Something like this:
var viewModelA = new ViewModelA();
self.selArtist = ko.observable(viewModelA.selectedArtist().value);
}
我试图做这样的事情:
self.selArtist = ko.computed(function () {
if(self.selectedArtist()){
return self.selectedArtist().ArtistId;
}
});
然后这样访问:
var viewModelA = new ViewModelA();
viewModelA.selArtist();
结果:undefined:
更新:
根据下面的评论,我稍微更改了代码,但我仍然无法从 viewModelA 访问选定的值。
例如这个有效:
self.firstName = ko.observable('Bob');
self.lastName = ko.observable('Smith');
self.fullName = ko.computed(function() {
return self.firstName() + " " + self.lastName();
});
这样调用:
var viewModelB = function(vma){
var self = this;
// Alert for example:
alert(vma.fullName());
};
var viewModelMain = (function(){
var self = this;
self.viewModelA = new viewModelA();
self.viewModelB = new viewModelB(self.viewModelA);
})();
如果我尝试调用 self.selectedArtist().value
它不会像上面所说的那样工作。
我问过a similar question on CodeReview。基本上,有三个选项:
- 将 parent 传递给 child 并在 child 视图模型中放置逻辑;
- 让parent处理children的一切;
- 创建管理服务/object 来处理这些事情。
我发现第三个选项在 Knockout 中表现不佳,但请注意,这主要是个人意见。
我发现当 child class 非常小 and/or 视图模型树中的叶节点时,第二个选项很有用。
我发现我通常最终会使用第一个选项。使用您提供给我们的代码,这对您来说也是最有意义的。例如:
function ViewModelB(parent){
var self = this;
self.selArtist = ko.computed(function () {
if(!!parent.selectedArtist()){
return parent.selectedArtist().id;
}
return undefined;
});
}
function ArtistVm(data) {
var self = this;
self.id = data.ArtistId;
self.firstName = ko.observable(data.FirstName);
self.lastName = ko.observable(data.LastName);
self.fullName = ko.pureComputed(function() {
return self.firstName() + ' ' + self.lastName();
});
}
function ViewModelA(){
var self = this;
self.selectedArtist = ko.observable(null);
self.artists = ko.observableArray(ko.utils.arrayMap(data,
function (artist) {
return new ArtistVm(artist);
});
});
self.viewModelB = ko.observable(new ViewModelB(self));
}
更新:工作解决方案:
你想做什么?
我需要将视图模型分解成更小的功能部分,以便将每个主要功能划分为它自己的功能(视图模型)。
你遇到了什么问题?
该应用程序包含一个 Select Option Binding
,我需要从另一个视图模型访问所选值,以便我可以使用该值作为参数来使用不同的视图模型执行其他绑定。
但是,我无法访问Selected Value
,当我终于解决了这个问题时,又出现了另一个问题,这次Select Options Binding
如果之前有任何依赖绑定将无法工作。
因为我使用选定值作为参数,如果使用参数的任何依赖绑定被放置在 select 选项 HTML 之上,代码将无法运行。 select 选项必须放在第一位:
解法:
HTML:
<!-- Binding with View Model B -->
<div id="artist-detail" data-bind="with: ArtistBio()[0]">
<p data-bind="text: ArtistId"></p>
<p data-bind="text: Bio"></p>
</div>
<!-- Binding with View Model A -->
<div id="artist-list">
<select data-bind="options: Artists,
optionsText: 'FullName', value: SelectedArtist"></select>
</div>
查看模型A:
function ViewModelA(){
var self = this;
self.SelectedArtist = ko.observable();
var artistList = [{
"ArtistId": "1",
"LastName": "Secada",
"FirstName": "Jon"
},
{
"ArtistId": "2",
"LastName": "Dion",
"FirstName": "Celine"
}];
self.Artists = ko.computed(function () {
return ko.utils.arrayMap(artistList,
function (artist) {
return {
FullName: artist.FirstName + ' ' + artist.LastName,
value: artist.ArtistId
}
});
});
}
查看模型 B:
function ViewModelB(vma){
var self = this;
var artistDetail = [{
"ArtistId": "1",
"Bio": "Jon Secada is a Cuban American singer and songwriter. " +
"Secada was born in Havana, Cuba, and raised in Hialeah, Florida. " +
"He has won two Grammy Awards and sold 20 million albums since his " +
"English-language debut album in 1992"
},
{
"ArtistId": "2",
"Bio": "Céline Marie Claudette Dion, CC OQ ChLD is a Canadian " +
"singer, songwriter, businesswoman and occasional actress."
}];
self.ArtistBio = ko.computed(function () {
if(vma.SelectedArtist()){
return ko.utils.arrayFilter(artistDetail, function (item) {
// Access the selected value here and return matching actist
return item.ArtistId === vma.SelectedArtist().value;
});
}
});
}
执行两个视图模型的绑定:
var viewModelA = new ViewModelA();
var viewModelB = new ViewModelB(viewModelA);
ko.applyBindings(viewModelA, document.getElementById('artist-list'));
ko.applyBindings(viewModelB, document.getElementById('artist-detail'));
使用此代码,我将 select 列表放在哪里并不重要,因为我首先调用并绑定到视图模型 A。
这是我学习的第四周KnockoutJS
所以请随时改进答案。
这是一个带有工作示例的 JSFiddle: