Параметры выпадающего меню / флажка не являются обязательными при первом нажатии после первой загрузки страницы в нокауте js - PullRequest
0 голосов
/ 08 января 2019

Я расследую ошибку в приложении ASP.net + knockout-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 голосов
/ 07 марта 2019

Добавление этого кода в 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
    });
});
0 голосов
/ 08 января 2019

Есть несколько исправлений в том, как вы пытаетесь связать. «Я» не определяется при инициализации настроек. Пожалуйста, проверьте следующее и убедитесь, что это имеет смысл.

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>
...