0

ノックアウトを使用して、あるテンプレートを別のテンプレートのコンテキストでレンダリングする問題を解決しようとしています。外側のテンプレートは、内側のテンプレートとそのビュー モデルを認識していないため、気にする必要はありません。それが気にするのは、それ自身のテンプレートであり、その名前とそのビューモデルを渡す内部テンプレートを埋め込む場所です。

したがって、理想的には、次のバインディングを実装する方法を知りたいと思います:

<script type="text/html" id="outerTemplate">
    <div class="outer-template" data-bind="here: {}"></div>
</script>

<!-- ko nested: { to: 'outerTemplate', data: { name: 'I am an inner view model' } } -->

    <div class="inner-template" data-bind="text: name"></div>

<!-- /ko -->

誰かがノックアウトをよく知っていて、そのような種類のバインディングを簡単に概説できるなら、私は大いに感謝します.

更新: 機能要求が提案されました: https://github.com/knockout/knockout/issues/1251

4

2 に答える 2

1

バインディングにより、template使用するテンプレート名を動的に選択できるため、次のようなことができます。

<script id="outer" type="text/html">
    <h2>Outer</h2>
    <div data-bind="template: { name: tmplName, data: data }"></div>
</script>

<script id="inner" type="text/html">
    <h3>Inner</h3>
    <input data-bind="value: name" />
</script>

<div data-bind="template: 'outer'"></div>

この場合、ビュー モデルは次のようになります。

var vm = {
    tmplName: 'inner',
    data: {
        name: ko.observable("Bob")   
    }
};

ko.applyBindings(vm);

ビュー モデルは、必要に応じて構造化できます。重要なのは、テンプレート名とデータをテンプレート バインディングに渡すことだけです。

サンプル: http://jsfiddle.net/rniemeyer/LHhc8/

于 2013-02-14T19:13:48.253 に答える
0

私が自分で作った実例があります:http://jsfiddle.net/m34wp/4/

var templateComputedDomDataKey = '__ko__templateComputedDomDataKey__';
function disposeOldComputedAndStoreNewOne(element, newComputed) {
    var oldComputed = ko.utils.domData.get(element, templateComputedDomDataKey);
    if(oldComputed && (typeof (oldComputed.dispose) == 'function')) {
        oldComputed.dispose();
    }
    ko.utils.domData.set(element, templateComputedDomDataKey, (newComputed && newComputed.isActive()) ? newComputed : undefined);
}
function makeArray(arrayLikeObject) {
    var result = [];
    for(var i = 0, j = arrayLikeObject.length; i < j; i++) {
        result.push(arrayLikeObject[i]);
    }
    ;
    return result;
}
function moveCleanedNodesToContainerElement(nodes) {
    var nodesArray = makeArray(nodes);
    var container = document.createElement('div');
    for(var i = 0, j = nodesArray.length; i < j; i++) {
        container.appendChild(ko.cleanNode(nodesArray[i]));
    }
    return container;
}
ko.bindingHandlers['nested'] = {
    'init': function (element, valueAccessor) {
        var elementType = 1;
        var commentType = 8;
        var bindingValue = ko.utils.unwrapObservable(valueAccessor());
        if(element.nodeType == elementType || element.nodeType == commentType) {
            // It's an anonymous template - store the element contents, then clear the element
            var templateNodes = element.nodeType == 1 ? element.childNodes : ko.virtualElements.childNodes(element);
            var container = moveCleanedNodesToContainerElement(templateNodes);
            new ko.templateSources.anonymousTemplate(element)['nodes'](container);
        }
        return {
            'controlsDescendantBindings': true
        };
    },
    'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var options = ko.utils.unwrapObservable(valueAccessor());
        var outerTemplateName = options['to'];
        var dataValue = ko.utils.unwrapObservable(options['data']) || viewModel;
        var innerContext = bindingContext['createChildContext'](dataValue);
        innerContext.innerTemplateElement = element;
        var templateComputed = ko.renderTemplate(outerTemplateName, innerContext, options, element);
        disposeOldComputedAndStoreNewOne(element, templateComputed);
    }
};
ko.bindingHandlers['here'] = {
    'init': function (element, valueAccessor) {
        return {
            'controlsDescendantBindings': true
        };
    },
    'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var templateElement = bindingContext.innerTemplateElement;
        if(viewModel != null) {
            var innerContext = bindingContext['createChildContext'](viewModel);
            var templateComputed = ko.renderTemplate(templateElement, innerContext, {
            }, element);
            disposeOldComputedAndStoreNewOne(element, templateComputed);
        } else {
        }
    }
};
ko.virtualElements.allowedBindings['nested'] = true;
于 2013-02-15T12:09:23.157 に答える