我正在调查ASP.net + knockout-3.1.0 app中的一个错误。
错误:我有一个弹出窗口,有很少的下拉菜单和复选框。有时,在第一次加载第一次点击打开弹出窗口后,它会显示空的下拉菜单/复选框。它很少发生,只发布弹出窗口。
码:
ASPX
<div id="campaignSettings" runat="server">
<div class="action modal-popup">
<a data-bind="click: settings.Show">Settings </a>
</div>
<div id="popupContainer">
<div id="dialog" class="window dialog-settings">
<div class="dialog-container">
<controls:Settings id="settings" runat="server"></controls:Settings>
</div>
</div>
</div>
</div>
<script type="text/javascript">
function loadKo() {
self.settings = new SettingsViewModel(self);
ko.applyBindings(self);
ko.applyBindings(self.settings, document.getElementById('koSettings'));
}
Sys.Application.add_init(loadKo);
</script>
Settings.ascx
<div id="koSettings">
<select data-bind="options: messageDropdown.Items, optionsText: 'Value', optionsValue: 'ID', value: messageDropdown.SelectedValue" ></select>
</div>
settings.js
function SettingsViewModel(parent) {
var self = this;
self.isVisible = ko.observable(false);
self.isLoaded = false;
self.SearchType = ko.observable(false);
self.ShowDefault = ko.observable();
self.messageDropdown = {
Items: ko.observableArray(),
SelectedValue: ko.observable()
};
self.preferences = ko.observableArray();
self.showDuration = ko.observable(false);
self.getPreference = function (list, id) {
var arr = ko.utils.arrayFilter(list, function (item) {
return item.PreferenceID() == id.PreferenceID;
});
return arr[0];
}
self.messageDropdown.SelectedValue.subscribe(function (data) {
if (data == 22) {
self.showDuration(false);
self.durationDropdown.SelectedValue(0);
}
else {
self.showDuration(true);
}
});
self.Show = function () {
if (self.isLoaded !== true) {
self.Load();
}
if (self.isVisible() !== true) {
self.LoadPreferences();
}
self.isVisible(true);
}
self.Cancel = function () {
self.isVisible(false);
}
self.Load = function () {
$.ajax({
type: "GET",
contentType: "application/json",
url: "rest/preference/load",
async: false,
context: document.body
}).done(function (data) {
ko.mapping.fromJS(data.Data, {}, self);
self.isLoaded = true;
self.SearchType(data.Data.SearchType);
});
}
self.LoadPreferences = function () {
$.ajax({
type: "GET",
contentType: "application/json",
url: "rest/preference/get",
async: false,
context: document.body
}).done(function (data) {
self.preferences.removeAll();
self.messageDropdown.SelectedValue(data.Data.SelectedMessage);
});
}
}
$(document).ready(function () {
$('.modal-popup').click(function (e) {
var att = $('.modal-popup').attr('disabled');
var isLinkDisabled = false;
e.preventDefault();
if (!$.browser.msie) {
if (att != 'disabled') {
isLinkDisabled = false;
}
else {
isLinkDisabled = true;
}
}
else {
if (att != true) {
isLinkDisabled = false;
}
else {
isLinkDisabled = true;
}
}
if (!isLinkDisabled) {
var id = $('#dialog');
setPopupPosition(id, e);
$(id).show('fast');
}
});
});
我注意到,当弹出显示为空时,有时不会触发self.Show函数。任何人可能有的见解将不胜感激。
您尝试绑定的方式几乎没有更正。初始化设置时未定义“self”。请检查以下内容,看看它是否有意义。
function SettingsViewModel(parent) {
var self = this;
self.isVisible = ko.observable(false);
self.isLoaded = false;
self.SearchType = ko.observable(false);
self.ShowDefault = ko.observable();
self.messageDropdown = {
Items: ko.observableArray(),
SelectedValue: ko.observable()
};
self.preferences = ko.observableArray();
self.showDuration = ko.observable(false);
self.getPreference = function (list, id) {
var arr = ko.utils.arrayFilter(list, function (item) {
return item.PreferenceID() == id.PreferenceID;
});
return arr[0];
}
self.messageDropdown.SelectedValue.subscribe(function (data) {
if (data == 22) {
self.showDuration(false);
self.durationDropdown.SelectedValue(0);
}
else {
self.showDuration(true);
}
});
self.Show = function () {
if (self.isLoaded !== true) {
self.Load();
}
if (self.isVisible() !== true) {
self.LoadPreferences();
}
self.isVisible(true);
}
self.Cancel = function () {
self.isVisible(false);
}
self.Load = function () {
self.messageDropdown.Items([{Value:"a", ID:1}, {Value:"b", ID:2}]);
}
self.LoadPreferences = function () {
self.messageDropdown.SelectedValue(1);
}
}
$(document).ready(function () {
var settings = new SettingsViewModel();
ko.applyBindings(settings);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div id="campaignSettings" runat="server">
<div class="action modal-popup">
<a data-bind="click: Show">Settings </a>
</div>
<div id="popupContainer">
<div id="dialog" class="window dialog-settings">
<div class="dialog-container">
<controls:Settings id="settings" runat="server"></controls:Settings>
</div>
</div>
</div>
</div>
<div id="koSettings">
<select data-bind="options: messageDropdown.Items(), optionsText: 'Value', optionsValue: 'ID', value: messageDropdown.SelectedValue()" ></select>
</div>
<script type="text/javascript">
</script>
在settings.js中添加此代码解决了我的问题:
$(document).ready(function () {
$('.modal-popup').click(function (e) {
var elementToBind = document.getElementById('koSettings');
var existingContext = ko.contextFor(elementToBind);
if (existingContext && existingContext.$data.isLoaded) {
// do nothing
}
else {
existingContext.$rawData.Load();
existingContext.$rawData.LoadPreferences();
}
// other lines
});
});