在首次敲入js中加载页面后,下拉/复选框选项未绑定在第一次点击上

时间:2019-01-08 11:19:48

标签: javascript asp.net knockout.js knockout-3.0

我正在调查ASP.net +淘汰赛3.1.0应用程序中的错误。

错误:我有一个带有一些下拉菜单和复选框的弹出窗口。有时,在首次单击以打开弹出窗口时加载第一页后,它会显示为空的下拉菜单/复选框。这种情况很少发生,只是弹出窗口的问题。

代码:

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函数。有人可能会提供的任何见解将不胜感激。

2 个答案:

答案 0 :(得分:0)

您尝试绑定的方式几乎没有更正。初始化设置时未定义“自我”。请检查以下内容,并使其有意义。

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>

答案 1 :(得分:0)

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
    });
});