Knockout.js动态选择模板错误:“找不到带ID的模板''”

时间:2014-10-06 15:17:13

标签: javascript jquery templates knockout.js

我的目标是显示“noSets”模板,如果observableArray长度小于0并使用项目详细信息渲染模板 - “showSets”,如果observableArray长度大于0.我想使用模板用于此目的,但FireBug显示错误:找不到ID为“templatename”的模板。 这是ViewModel:

function SetsViewModel() {
            var self = this;
            self.usersets = ko.observableArray();
            self.getTemplate = function () {
                return self.usersets().length > 0 ? "showSets" : "noSets";
            }
  }
$(document).ready(function () {
            ko.applyBindings(new SetsViewModel(), document.getElementById('user_sets'));
});

这是HTML标记:

<div data-bind="template: { name: $root.getTemplate, foreach: usersets }" id="user_sets">
            <script type="text/html" id="noSets">
                <p>You do not have items yet.</p>
            </script>
            <script type="text/html" id="showSets">
                <div class="block">
                    <input type="hidden" data-bind="value: $data.SetId" />
                    <div class="fav" data-bind="css: { fullop: $data.IsFavorite == true }">
                        <img alt="" src="img/fav.png" data-bind="click: $root.setFavorite">
                    </div>
                    <div>
                        <img alt="" data-bind="attr: { src: $data.SetImg }">
                    </div>
                    <div class="txt">
                        <h3 data-bind="text: $data.SetName, click: $root.go"></h3>
                        <p><span data-bind="text: $data.ItemsNumber + ' вещей,'"></span><span data-bind="    text: ' общая цена ' + $data.SetPrice + ' руб'"></span></p>
                    </div>
                </div>
            </script>
        </div>

我该如何解决?

2 个答案:

答案 0 :(得分:1)

您可以在div之外声明您要绑定的模板作为解决方法。正如@JeffMercado所说:

  

实际问题是,由于user_sets使用模板绑定,因此主体将被丢弃(以及模板及其中)

&#13;
&#13;
function SetsViewModel() {
            var self = this;
            self.usersets = ko.observableArray([{SetId: 1, SetName: 'Name 1'}]);
            self.getTemplate = function () {
                return self.usersets().length > 0 ? "showSets" : "noSets";
            }
  }
$(document).ready(function () {
            ko.applyBindings(new SetsViewModel(), document.getElementById('user_sets'));
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script type="text/html" id="noSets">
    <p>You do not have items yet.</p>
</script>
<script type="text/html" id="showSets">
    <div class="block">
        <input data-bind="value: $data.SetId" />
        <div class="txt">
            <h3 data-bind="text: 'Set name:' + $data.SetName"></h3>                        
        </div>
    </div>
</script>

<div data-bind="template: { name: getTemplate, foreach: usersets }" id="user_sets">
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我认为命名模板可能是针对此特定问题的错误方法 - 它们更适用于您希望每个项目使用不同模板的情况,这不是这里的情况。相反,当有0个项目时显示完全不同的div会更合适:

<div data-bind="visible: usersets().length == 0">
    You have no sets
</div>

<div data-bind="visible: usersets().length > 0, foreach: usersets" id="user_sets">
    <div class="block">
        <input type="hidden" data-bind="value: $data.SetId" />
        <div class="fav" data-bind="css: { fullop: $data.IsFavorite == true }">
            <img alt="" src="img/fav.png" data-bind="click: $root.setFavorite">
        </div>
        <div>
            <img alt="" data-bind="attr: { src: $data.SetImg }">
        </div>
        <div class="txt">
            <h3 data-bind="text: $data.SetName, click: $root.go"></h3>
            <p><span data-bind="text: $data.ItemsNumber + ' вещей,'"></span><span data-bind="    text: ' общая цена ' + $data.SetPrice + ' руб'"></span></p>
        </div>
    </div>
</div>