当重新显示模态时,KnockoutJS bindingHandler调用init

时间:2014-07-16 22:52:01

标签: knockout.js

我使用knockout js与Bootstrap一起在页面上显示模态窗口。我还有以下扩展来从标记中获取值,以便我的observable可以从剃刀中填充:

  ko.bindingHandlers.initializeValue = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel);
        valueAccessor()(element.getAttribute('value'));

    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

        var value = ko.utils.unwrapObservable(valueAccessor());

        if (element.nodeName == 'SPAN')
            element.innerHTML = value;

        element.setAttribute('value', value);

    }
};

这非常有用,可以在第一次使用razor加载页面时填充挖空视图模型。当我从模态内部更新值时,将调用更新,并更新observable以及所有这些。问题是我关闭模态窗口,然后重新打开它。它在bindingHandler上再次调用init并重置了原始值属性中的值,尽管我将属性设置为更新函数底部的新值。

所以我的问题是:为什么在重新打开模态时再次调用初始化?我知道当模态隐藏时,标记会从DOM中删除,但是模态可观察的值是否仍然在内存中?

以下是我的整个页面的视图模型,以及弹出窗口的视图模型:

var userEditViewModel = function () {
            var self = this;
            self.template = 'editUserTemplate';
            self.hasChanges = ko.observable(false);
            self.isCanceling = ko.observable(false);

            self.FirstName = ko.observable();
            self.LastName = ko.observable();
            self.EmailAddress = ko.observable();

            self.onYes = function() {
                self.modal.close();
                self.isCanceling(false);
                self.hasChanges(false);
            };

            self.onNo = function () {
                self.isCanceling(false);
            };

            self.onSave = function () {
                if (self.errors().length == 0) {
                    var options =
                    {
                        FirstName: self.FirstName(),
                        LastName: self.LastName(),
                        Email: self.EmailAddress()
                    };
                    repo.SaveProfile(options, function (result) {
                        self.modal.close(result.result);
                    });
                } else {
                    self.errors.showAllMessages();
                }
            };

            self.onCancel = function () {
                if (self.hasChanges() == false) {
                    this.modal.close();
                } else {
                    self.isCanceling(true);
                }
            };

            self.errors = ko.validation.group(self);
        }

        }

        var profileViewModel = (function () {
            var self = this;

            self.FirstName = ko.observable();
            self.LastName = ko.observable();
            self.EmailAddress = ko.observable();

            self.EditUserModel = new userEditViewModel();

            self.EditUser = function () {
                bhn.ShowModal({
                    viewModel: self.EditUserModel,
                    context: this 
                })
                .done(function (result) {

                })
                .fail(function () {

                })
                .then(self._updateProfile);
            }

            self._updateProfile = (function (result) {
                self.FirstName(result.firstName);
                self.LastName(result.lastName);
                self.EmailAddress(result.email);

            });
        });

模态代码:

function createModal(templateName, viewModel) {
    var temporaryDiv = addHiddenDivToBody();
    var deferredElement = $.Deferred();

    ko.renderTemplate(
        templateName,
        viewModel,
        {
            afterRender: function (nodes) {
                var elements = nodes.filter(function (node) {
                    return node.nodeType === 1;
                });
                deferredElement.resolve(elements[0]);
            }
        },
        temporaryDiv,
        "replaceNode"
    );

    return deferredElement;
}

function showModal(options) {
    if (typeof options === "undefined" || options === null) throw new Error("An options argument is required.");
    if (typeof options.viewModel !== "object") throw new Error("options.viewModel is required.");

    var viewModel = options.viewModel;
    var template = options.template || viewModel.template;
    var context = options.context;

    if (!template) throw new Error("options.template or options.viewModel.template is required.");

    return createModal(template, viewModel)
        .pipe($)
        .pipe(function ($ui) {
            var deferredModalResult = $.Deferred();
            addModalHelperToViewModel(viewModel, deferredModalResult, context);
            showTwitterBootstrapModal($ui);
            whenModalResultCompleteThenHideUi(deferredModalResult, $ui);
            whenUiHiddenThenRemoveUi($ui);
            return deferredModalResult;
        });

}

function addHiddenDivToBody() {
    var div = document.createElement("div");
    div.style.display = "none";
    document.body.appendChild(div);
    return div;
};

function addModalHelperToViewModel(viewModel, deferredModalResult, context) {
    viewModel.modal = {
        close: function (result) {
            if (typeof result !== "undefined") {
                deferredModalResult.resolveWith(context, [result]);
            } else {
                deferredModalResult.rejectWith(context, []);
            }
        }
    };
};

function showTwitterBootstrapModal($ui) {
    // Display the modal UI using Twitter Bootstrap's modal plug-in.
    $ui.modal({
        backdrop: "static",
        keyboard: false
    });
};

function whenModalResultCompleteThenHideUi(deferredModalResult, $ui) {
    deferredModalResult.always(function () {
        $ui.modal("hide");
    });
};

function whenUiHiddenThenRemoveUi($ui) {
    $ui.on("hidden", function () {
        //$ui.each(function (index, element) { ko.cleanNode(element); });
        //$ui.remove();
    });
};

0 个答案:

没有答案