KnockoutJS - 模板

模板是一组可重复使用的 DOM 元素。模板具有最小化 DOM 元素重复的特性,因此可以轻松构建复杂的应用程序。

有两种创建模板的方法。

  • 本机模板 − 此方法支持控制流绑定,例如 foreach、with 和 if。这些绑定捕获元素中现有的 HTML 标记并将其用作随机项目的模板。此模板不需要外部库。

  • 基于字符串的模板 − KO 连接到第三方引擎以将 ViewModel 值传递给它,并将生成的标记注入文档。例如,JQuery.tmpl 和 Underscore Engine。

语法

template: <parameter-value>

<script type = "text/html" id = "template-name">
   ...
   ...   // DOM elemets to be processed
   ...
</script>

请注意,脚本块中的 typetext/html 形式提供,以通知 KO,它不是可执行块,而只是需要呈现的模板块。

参数

以下属性的组合可以作为参数值发送给模板。

  • name − 这表示模板的名称。

  • nodes − 这表示要用作模板的 DOM 节点数组。如果传递了 name 参数,则忽略此参数。

  • data − 这只不过是通过模板显示的数据。

  • if −如果给定条件的结果为 true 或类似 true 的值,则将提供模板。

  • foreach − 以 foreach 格式提供模板。

  • as − 这只是在 foreach 元素中创建一个别名。

  • afterAdd、afterRender、beforeRemove − 这些都是表示根据执行的操作而执行的可调用函数。

观察

渲染命名模板

与控制流绑定一起使用时,模板由 DOM 内的 HTML 标记隐式定义。但是,如果您愿意,可以将模板分解为单独的元素,然后按名称引用它们。

示例

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Named Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', data: friend1 }"></div>
      <div data-bind = "template: { name: 'friend-template', data: friend2 }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friend1 = { 
               name: 'Smith', 
               contactNumber: 4556750345, 
               email: 'smith123@gmail.com' 
            };
            
            this.friend2 = { 
               name: 'Jack', 
               contactNumber: 6789358001, 
               email: 'jack123@yahoo.com' 
            };
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

输出

让我们执行以下步骤来查看上述代码的工作原理 −

  • 将上述代码保存在 template-named.htm 文件中。

  • 在浏览器中打开此 HTML 文件。

  • 此处,friend-template 使用了 2 次。

在模板中使用"foreach"

以下是将 foreach 参数与模板一起使用的示例名称。

示例

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - foreach used with Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', foreach: friends }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = [
               { name: 'Smith', contactNumber: 4556750345, email: 'smith123@gmail.com' },
               { name: 'Jack', contactNumber: 6789358001, email: 'jack123@yahoo.com' },
               { name: 'Lisa', contactNumber: 4567893131, email: 'lisa343@yahoo.com' }
            ]
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

输出

让我们执行以下步骤来查看上述代码的工作原理 −

  • 将上述代码保存在 template-foreach.htm 文件中。

  • 在浏览器中打开此 HTML 文件。

  • 此处,foreach 控件用于模板绑定。

使用关键字为 foreach 项目创建别名

以下是如何为 foreach 项目创建别名−

<div data-bind = "template: { 
   name: 'friend-template', 
   foreach: friends, 
   as: 'frnz' 
}"></div>

通过创建别名,可以轻松地从 foreach 循环内部引用父对象。当代码复杂且嵌套多层时,此功能非常有用。

示例

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - using alias in Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <ul data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends, 
         as: 'frnz' 
      }"></ul>

      <script type = "text/html" id = "friend-template">
         <li>
            <h3 data-bind = "text: name"></h3>
            <span>Contact Numbers</span>
            <ul data-bind = "template: { 
               name : 'contacts-template', 
               foreach:contactNumber, 
               as: 'cont'
            } "></ul>
            <p>Email-id: <span data-bind = "text: email"></span></p>
         </li>
      </script>

      <script type = "text/html" id = "contacts-template">
         <li>
            <p><span data-bind = "text: cont"></span></p>
         </li>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = ko.observableArray ( [
               { 
                  name: 'Smith', 
                  contactNumber: [ 4556750345, 4356787934 ], 
                  email: 'smith123@gmail.com' 
               },
               
               { 
                  name: 'Jack', 
                  contactNumber: [ 6789358001, 3456895445 ], 
                  email: 'jack123@yahoo.com' 
               },
               
               { 
                  name: 'Lisa', 
                  contactNumber: [ 4567893131, 9876456783, 1349873445 ],  
                  email: 'lisa343@yahoo.com' 
               }
            ]);
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

输出

让我们执行以下步骤来查看上述代码的工作原理 −

  • 将上述代码保存在 template-as-alias.htm 文件中。

  • 在浏览器中打开此 HTML 文件。

  • 使用别名代替数组的全名。

使用 afterAdd、beforeRemove 和 afterRender

在某些情况下,需要在模板创建的 DOM 元素上运行额外的自定义逻辑。在这种情况下,可以使用以下回调。假设您正在使用 foreach 元素,那么 −

afterAdd − 当新项目添加到 foreach 中提到的数组时,将调用此函数。

beforeRemove − 此函数在从 foreach 中提到的数组中删除项目之前调用。

afterRender − 每次呈现 foreach 并将新条目添加到数组时,都会调用此处提到的函数。

示例

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Use of afterRender Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
      <script src = "https://code.jquery.com/jquery-2.1.3.min.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends , 
         afterRender: afterProcess
      }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
         <button data-bind = "click: $root.removeContact">remove </button>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            self = this;
            this.friends = ko.observableArray ([
               { name: 'Smith', contactNumber: 4556750345, email: 'smith123@gmail.com' },
               { name: 'Jack', contactNumber: 6789358001, email: 'jack123@yahoo.com' },
            ])

            this.afterProcess = function(elements, data){
               $(elements).css({color: 'magenta' });
            }

            self.removeContact = function() {
               self.friends.remove(this);
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
   </body>
</html>

输出

让我们执行以下步骤来查看上述代码的工作原理 −

  • 将上述代码保存在 template-afterrender.htm 文件中。

  • 在浏览器中打开此 HTML 文件。

  • 此处,每次呈现 foreach 时都会执行 afterProcess 函数。

动态选择模板

如果有多个可用模板,则可以通过将名称设为 observable 参数来动态选择一个。因此,随着名称参数的变化,模板值将被重新评估,进而数据将被重新呈现。

示例

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Dynamic Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: whichTemplate, 
         foreach: friends 
      }"></div>

      <script type = "text/html" id = "only-phon">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
      </script>

      <script type = "text/html" id = "only-email">
         <h3 data-bind = "text: name"></h3>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
   
            this.friends = ko.observableArray ([
               {
                  name: 'Smith', 
                  contactNumber: 4556750345, 
                  email: 'smith123@gmail.com', 
                  active: ko.observable(true)
               },
               
               {
                  name: 'Jack', 
                  contactNumber: 6789358001, 
                  email: 'jack123@yahoo.com', 
                  active: ko.observable(false)
               },
            ]);

            this.whichTemplate = function(friends) {
               return friends.active() ? "only-phon" : "only-email";
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

输出

让我们执行以下步骤来查看上述代码的工作原理 −

  • 将上述代码保存在 template-dynamic.htm 文件中。

  • 在浏览器中打开此 HTML 文件。

  • 要使用的模板取决于活动标志值。

使用基于外部字符串的引擎

本机模板可与各种控制流元素完美配合,即使使用嵌套代码块也是如此。 KO 还提供了一种与外部模板库(如 Underscore 模板引擎或 JQuery.tmpl)集成的方法。

正如官方网站上所述,JQuery.tmpl 自 2011 年 12 月起不再积极开发。因此,仅推荐使用 KO 的原生模板,而不是 JQuery.tmpl 或任何其他基于字符串的模板引擎。

有关此内容的更多详细信息,请参阅官方网站