【问题标题】:Using a variable to store a knockout template使用变量存储剔除模板
【发布时间】:2013-01-30 19:16:19
【问题描述】:

到目前为止,对淘汰赛的新手和喜爱它把一个 700 行的 jQuery 乱七八糟的东西剪成了 150 行。我不太喜欢的一个部分是模板。我希望能够创建一个类似的文件

module.ViewModel.views = {
   'view1' : '<div data-bind="foreach: data">TEMPLATE</div>'
};

// in my view model set something like 
ViewModel.view1Template = module.ViewModel.views.view1;

// then in my html have
<div data-bind="template: view1Template()"></div>

如果这很重要,我希望能够用小胡子做到这一点,但是 真的,我只是想为我的模板添加可重用性,而不是拥有它们 由 html 中的 ID 直接引用。我想这样做的另一个原因 在我的视图文件夹中,我还有其他使用小胡子但不淘汰的模板 希望在所有 JS 模板中保持我的格式一致。

更新

下面的答案似乎是目前最接近我想做的事情 我做的略有不同

for (var view in module.views){
    var node = $("<script/>", {
        "type" : "text/html",
        "id" : view,
        "text" : module.views[view]
    }).appendTo("body");
}

【问题讨论】:

    标签: knockout.js mustache knockout-2.0 templating


    【解决方案1】:

    您可以将元素动态插入到 DOM 中,然后应用 ko 绑定:

    var html = $.parseHtml(module.ViewModels.views['view1'])[0];
    ko.applyBindings(model, html);
    $('#content').append(html);
    

    现场演示

    http://jsfiddle.net/bikeshedder/VHUcF/


    我刚刚意识到我可能只回答了你问题的一半。遗憾的是,模板绑定处理程序只接受 element id 作为参数,没有元素。然而,这很容易通过在应用绑定之前将模板添加到 DOM 来解决:

    HTML

    <script id="templates" type="text/html"></script>
    
    <div id="content" data-bind="template: templates.answerList.id"></div>
    

    JavaScript

    var templates = {
        answerList: '<ul class="answer-list" data-bind="template: { name: templates.answer.id, foreach: answers }"></ul>',
        answer: '<div class="answer" data-bind="text: text"></div>'
    };
    
    // insert templates into DOM
    for (var name in templates) {
        var html = templates[name];
        var element = document.createElement('div');
        $(element).append($.parseHTML(html)[0]);
        element.id = 'tpl_' + name;
        $(element).attr('id', element.id);
        templates[name] = element;
        $('#templates').append(element);
    }
    
    answerModel = {
        answers: [
            { text: 1 },
            { text: 42 },
            { text: 667 }
        ],
        templates: templates
    };
    
    ko.applyBindings(answerModel, $('#content')[0]);
    

    现场演示

    http://jsfiddle.net/bikeshedder/VHUcF/1/

    【讨论】:

      【解决方案2】:

      我刚刚想出了一个更好的解决方案来解决这个问题。它不再需要您在指定模板时添加“.name”。

      HTML

      <script id="templates" type="text/html"></script>
      
      <div id="content" data-bind="template: templates.answerList"></div>
      

      JavaScript

      var templates = {
          answerList: 'Answers: <ul class="answer-list" data-bind="template: { name: templates.answer, foreach: answers }"></ul>',
          answer: '<li class="answer" data-bind="text: text"></li>'
      };
      
      var templateIds = {};
      
      for (var name in templates) {
          var id = 'tpl_' + name;
          $(document.createElement('div'))
              .append($.parseHTML(templates[name]))
              .attr('id', 'tpl_' + name)
              .appendTo('#templates');
          templateIds[name] = id;
      }
      
      answerModel = {
          answers: [
              { text: 1 },
              { text: 42 },
              { text: 667 }
          ],
          templates: templateIds
      };
      
      ko.applyBindings(answerModel, $('#content')[0]);
      

      现场演示

      http://jsfiddle.net/bikeshedder/VHUcF/3/

      注意

      此尝试要求您将templates 作为模型属性传递或在全局范围内定义templates。你也可以只写"tpl_" + ' 我觉得用起来更自然。

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

      如果您不想将包含模板的 script 元素放在 HTML 中,也可以从 JavaScript 中创建它。

      【讨论】:

        猜你喜欢
        • 2013-09-15
        • 1970-01-01
        • 2019-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-10
        • 1970-01-01
        相关资源
        最近更新 更多