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(テンプレートname名) とdata.

これが機能する方法はcurrentModal、データが入力されている場合、現在のテンプレートとデータを使用してモーダルが表示されるというものです。null の場合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");
    }
};

これに加えて必要なのは、モーダルの 1 つの要素だけです

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

ページのどこかで、currentModal オブザーバブルに書き込んでダイアログを開き、null にしてダイアログを閉じます: currentModal(null)

そこでは、テンプレート名として計算できるブートストラップ 3.0-rc1 ノックアウト 2.3 を使用しています:)

これを投稿してくれてありがとう@rp-niemeyer!

于 2013-07-29T14:48:46.863 に答える