我有以下数据结构
[{
"name": "root1",
"ecomCategories": [{
"name": "sub11"
}, {
"name": "sub12",
"ecomCategories": null
}, {
"name": "sub13",
"ecomCategories": null
}]
}, {
"name": "root2",
"ecomCategories": [{
"name": "sub21",
"ecomCategories": null
}]
}]
现在我想显示在选择根类别时会发生变化的下拉菜单: 请看这个小提琴 - jsfiddle
但是如果我正在更新订阅函数中的任何observable,那么它的更改将反映在父可观察
中在小提琴中重现此问题的步骤:
选择根类别" root1"它将有3个子类别sub11,sub12,sub13
选择任何子类别,即sub11
选择根类别" root2"
再次选择根类别" root1" 现在您将看到子类别中只有一个子类别下拉,因为它应该有3个子类别
// Here's my data model
var ViewModel = function() {
this.rootCategory = ko.observableArray([{
"name": "root1",
"ecomCategories": [{
"name": "sub11"
}, {
"name": "sub12",
"ecomCategories": null
}, {
"name": "sub13",
"ecomCategories": null
}]
}, {
"name": "root2",
"ecomCategories": [{
"name": "sub21",
"ecomCategories": null
}]
}]);
this.newObjectToSave = ko.observable();
this.selectedCategory = ko.observable();
this.selectedSubCategory = ko.observable();
var that = this;
//subscribers
this.selectedCategory.extend({
notify: 'always'
});
this.selectedCategory.subscribe(function(newVal) {
if (newVal != undefined) {
that.newObjectToSave(newVal);
// newObjectToSave().ecomCategories = [];
}
});
this.selectedSubCategory.extend({
notify: 'always'
});
this.selectedSubCategory.subscribe(function(subCat) {
if (subCat != undefined) {
that.newObjectToSave().ecomCategories = [subCat];
that.newObjectToSave(that.newObjectToSave().ecomCategories[0]);
}
});
//computed
this.subCategories = ko.computed(function() {
if (this.selectedCategory() != undefined) {
return this.selectedCategory().ecomCategories;
} else {
return "";
}
}, this);
};
ko.applyBindings(new ViewModel()); // This makes Knockout get to work

.paddingTop15 {
padding-top: 15px;
}
.browseCategory select {
-webkit-appearance: none;
/*Removes default chrome and safari style*/
-moz-appearance: none;
/* Removes Default Firefox style*/
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="container">
<div class="row paddingTop15">
<div class="col-lg-2">
Select Root Category:
<br>
<div class="btn-group btn-group-sm browseCategory">
<select class="btn btn-default" data-bind="options: rootCategory,
optionsText: 'name',
value: selectedCategory,
optionsCaption: 'Select Category'"></select>
</div>
</div>
</div>
<div class="row paddingTop15">
<div class="col-lg-2">
Select SubCategory:
<br>
<div class="btn-group btn-group-sm browseCategory">
<select class="btn btn-default" data-bind="options: subCategories,
optionsText: 'name',
value: selectedSubCategory,
optionsCaption: 'Select Sub Category'"></select>
</div>
</div>
</div>
</div>
&#13;
为什么更新&#34; newObjectToSave&#34;正在更新&#34; selectedCategory&#34;价值???
答案 0 :(得分:0)
您正面临的问题正在发生,因为您通过引用<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<MediaElement x:Name="playMedia" AutoPlay="True"/>
<StackPanel>
<Slider Name="slider" Margin="50,0"
Value="{Binding Position, ElementName=playMedia, Converter={StaticResource TimeSpanToTicksConverter}, Mode=TwoWay}"
Maximum="{Binding NaturalDuration.TimeSpan, ElementName=playMedia, Converter={StaticResource TimeSpanToTicksConverter}, Mode=OneWay}" />
<Button Name="btnNewSong" Content="New Song" HorizontalAlignment="Center" Margin="0,50,0,0" Click="btnNewSong_Click"/>
</StackPanel>
</Grid>
传递<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<MediaElement x:Name="playMedia" AutoPlay="True"/>
<StackPanel>
<Slider Name="slider" Margin="50,0"
Value="{x:Bind playMedia.Position, Converter={StaticResource TimeSpanToTicksConverter}, Mode=TwoWay}"
Maximum="{x:Bind playMedia.NaturalDuration.TimeSpan, Converter={StaticResource TimeSpanToTicksConverter}, Mode=OneWay}" />
<Button Name="btnNewSong" Content="New Song" HorizontalAlignment="Center" Margin="0,50,0,0" Click="btnNewSong_Click"/>
</StackPanel>
</Grid>
。那时 private async void btnNewSong_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.MusicLibrary;
openPicker.FileTypeFilter.Add(".wav");
openPicker.FileTypeFilter.Add(".mp3");
openPicker.FileTypeFilter.Add(".m4a");
StorageFile storageFile = await openPicker.PickSingleFileAsync();
if (storageFile != null)
{
var contentType = storageFile.ContentType;
playMedia.SetSource(await storageFile.OpenAsync(FileAccessMode.Read), contentType);
playMedia.Play();
}
}
可观察的值链接到public class TimeSpanToTicksConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
TimeSpan ts = (TimeSpan)value;
double result = System.Convert.ToDouble(ts.Ticks);
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
double ticks = (double)value;
TimeSpan ts = new TimeSpan(System.Convert.ToInt64(ticks));
return ts;
}
}
newVal
...然后在引用的值上修改ecomCategories,导致选项修改:
newObjectToSave
解决方案:我建议深度复制newVal对象,以便在之后修改它时不会将其链接到原始值:
newObjectToSave
工作fiddle