5

我要做的是创建一个 DOM 节点,使用 ko.renderTemplate 覆盖创建的节点呈现模板,然后在该模板中都能够从特定模型和 viewModel $root 获取数据。

前任:

var data = new ModelData();
var domNode = document.createElement("div");
document.body.appendChild(domNode);
ko.renderTemplate('template', data, {}, domNode, 'replaceNode');

模板可能如下所示:

<script type="text/html" id="template">
    <span data-bind="text: DataFromModel"></span>
    <ul data-bind="foreach: $root.DataFromViewModelRoot">
    </ul>
</script>

在这种情况下,我没有从 $root.DataFromViewModelRoot 获得任何数据,因为它认为 $root-data 是 ModelData(我明白为什么,我只是不知道该怎么做)。

我想要完成的是我需要从模板创建一个模态窗口(引导程序),然后我希望能够根据我“发送给它的数据”在该模态中显示不同的内容”。我还需要能够创建多个模式,这就是为什么我需要创建一个新的 DOM 节点。

4

2 回答 2

5

这与您的具体问题略有不同,但这是使用引导模式的另一种方法。

您可以使用包含引导程序modal和绑定的自定义template绑定。

绑定可能如下所示:

ko.bindingHandlers.modal = {
    init: function(element, valueAccessor, allBindings, vm, context) {
        var modal = valueAccessor();
        //init the modal and make sure that we clear the observable no matter how the modal is closed
        $(element).modal({ show: false, backdrop: 'static' }).on("hidden.bs.modal", function() {
            if (ko.isWriteableObservable(modal)) {
                modal(null);
            }
        });

        //template's name field can accept a function to return the name dynamically
        var templateName = function() {
            var value = modal();
            return value && value.name;
        };

        //a computed to wrap the current modal data
        var templateData = ko.computed(function() {
            var value = modal();
            return value && value.data;
        });

        //apply the template binding to this element
        ko.applyBindingsToNode(element, { template: { 'if': modal, name: templateName, data: templateData } }, context);

        //tell KO that we will handle binding the children (via the template binding)
        return { controlsDescendantBindings: true };
    },
    update: function(element, valueAccessor) {
        var data = ko.utils.unwrapObservable(valueAccessor());
        //show or hide the modal depending on whether the associated data is populated
        $(element).modal(data ? "show" : "hide");
    }
};

现在,您将在页面上绑定一个模式,例如:

<div class="modal hide fade" data-bind="modal: currentModal"></div>

currentModal将是一个 observable,您使用包含name(模板名称) 和data.

其工作方式是,如果currentModal已填充,则使用当前模板和数据显示模式。如果currentModal为空,则模式关闭。

这是一个如何工作的示例:http: //jsfiddle.net/rniemeyer/NJtu7/

于 2013-04-23T03:15:43.550 回答
1

我有一个改进版的https://stackoverflow.com/a/16160300/2630724可以分享:

ko.bindingHandlers.modal = {
    init: function(element, valueAccessor, allBindings, vm, context) {
        var modal = valueAccessor();

        //init the modal and make sure that we clear the observable no matter how the modal is closed
        $(element).modal({show: false}).on("hidden.bs.modal", function() {
            if (ko.isWriteableObservable(modal)) {
                modal(null);
            }
        });

        var template_computed = ko.computed({
            read: function() {
                var value = modal();
                return value ? value : {'if': false};
            },
            disposeWhenNodeIsRemoved: element
        });

        //apply the template binding to this element
        return ko.applyBindingsToNode(element, { template: template_computed }, context);
    },
    update: function(element, valueAccessor) {
        var data = ko.utils.unwrapObservable(valueAccessor());
        //show or hide the modal depending on whether the associated data is populated
        $(element).modal(data ? "show" : "hide");
    }
};

除此之外,您还需要一个模态元素

<div class="modal fade" data-bind="modal: currentModal">
</div>

在页面上的某处,然后通过写入 currentModal 可观察对象打开一个对话框,然后通过将其置空来关闭对话框: currentModal(null)

我在那里使用 bootstrap 3.0-rc1 淘汰赛 2.3,它允许计算为模板名称:)

感谢@rp-niemeyer 发布此消息!

于 2013-07-29T14:48:46.863 回答