template 订阅
XSL 样式表由一个或多套被称为模板(template)的规则组成。 展开全文
XSL 样式表由一个或多套被称为模板(template)的规则组成。
信息
举    例
match="/" 定义整个文档
用    于
构建模板
中文名
template
简化版本
template正文
每个模板含有当某个指定的节点被匹配时所应用的规则。 [1]  元素用于构建模板。 [1]  match 属性用于关联 XML 元素和模板。match 属性也可用来为整个文档定义模板。match 属性的值是 XPath 表达式(举例,match="/" 定义整个文档)。 [1] 
收起全文
精华内容
下载资源
问答
  • template
    千次阅读
    2021-01-13 15:14:09

    模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型

    模板是一种对类型进行参数化的工具;

    通常有两种形式:函数模板和类模板;

    函数模板针对仅参数类型不同的函数;

    类模板针对仅数据成员和成员函数类型不同的类。

    使用模板的目的就是能够让程序员编写与类型无关的代码。比如编写了一个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型无法实现,要实现这些类型的交换就要重新编写另一个swap函数。使用模板的目的就是要让这程序的实现与类型无关,比如一个swap模板函数,即可以实现int 型,又可以实现double型的交换。模板可以应用于函数和类。下面分别介绍。

    注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。

    一、函数模板通式

    函数模板的格式:

    template <class 形参名,class 形参名,......> 返回类型 函数名(参数列表)
    {
        函数体
    }

    其中template和class是关键字,class可以用typename 关键字代替,在这里typename 和class没区别<>括号中的参数叫模板形参,模板形参和函数形参很相像,模板形参不能为空。一但声明了模板函数就可以用模板函数的形参名声明类中的成员变量和成员函数,即可以在该函数中使用内置类型的地方都可以使用模板形参名。模板形参需要调用该模板函数时提供的模板实参来初始化模板形参,一旦编译器确定了实际的模板实参类型就称他实例化了函数模板的一个实例。比如swap的模板函数形式为:

    template <class T> void swap(T& a, T& b){},

    当调用这样的模板函数时类型T就会被被调用时的类型所代替,比如swap(a,b)其中abint 型,这时模板函数swap中的形参T就会被int 所代替,模板函数就变为swap(int &a, int &b)。而当swap(c,d)其中cddouble类型时,模板函数会被替换为swap(double &a, double &b),这样就实现了函数的实现与类型无关的代码。

    注意:对于函数模板而言不存在 h(int,int) 这样的调用,不能在函数调用的参数中指定模板形参的类型,对函数模板的调用应使用实参推演来进行,即只能进行 h(2,3) 这样的调用,或者int a, b; h(a,b)

    函数模板的示例演示将在下文中涉及!

    二、类模板通式

    1、类模板的格式为:

    template<class  形参名,class 形参名,…>   class 类名
    { ... };

    类模板和函数模板都是以template开始后接模板形参列表组成模板形参不能为空,一但声明了类模板就可以用类模板的形参名声明类中的成员变量和成员函数,即可以在类中使用内置类型的地方都可以使用模板形参名来声明。比如

    template<class T> class A{public: T a; T b; T hy(T c, T &d);};

    在类A中声明了两个类型为T的成员变量a和b,还声明了一个返回类型为T带两个参数类型为T的函数hy。

    2、类模板对象的创建:比如一个模板类A,则使用类模板创建对象的方法为A<int> m;在类A后面跟上一个<>尖括号并在里面填上相应的类型,这样的话类A中凡是用到模板形参的地方都会被int 所代替。当类模板有两个模板形参时创建对象的方法为A<int, double> m;类型之间用逗号隔开。

    3、对于类模板,模板形参的类型必须在类名后的尖括号中明确指定。比如A<2> m;用这种方法把模板形参设置为int是错误的(编译错误:error C2079: 'a' uses undefined class 'A<int>'),类模板形参不存在实参推演的问题。也就是说不能把整型值2推演为int 型传递给模板形参。要把类模板形参调置为int 型必须这样指定A<int> m

    4、在类模板外部定义成员函数的方法为:

    template<模板形参列表> 函数返回类型 类名<模板形参名>::函数名(参数列表){函数体},

    比如有两个模板形参T1,T2的类A中含有一个void h()函数,则定义该函数的语法为:

    template<class T1,class T2> void A<T1,T2>::h(){}。

    注意:当在类外面定义类的成员时template后面的模板形参应与要定义的类的模板形参一致

    5、再次提醒注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。

    三、模板的形参

    有三种类型的模板形参:类型形参,非类型形参和模板形参。

    1、类型形参

    1.1 、类型模板形参:类型形参由关键字class或typename后接说明符构成,如template<class T> void h(T a){};其中T就是一个类型形参,类型形参的名字由用户自已确定模板形参表示的是一个未知的类型。模板类型形参可作为类型说明符用在模板中的任何地方,与内置类型说明符或类类型说明符的使用方式完全相同,即可以用于指定返回类型,变量声明等。

    作者原版:1.2、不能为同一个模板类型形参指定两种不同的类型,比如template<class T>void h(T a, T b){},语句调用h(2, 3.2)将出错,因为该语句给同一模板形参T指定了两种类型,第一个实参2把模板形参T指定为int,而第二个实参3.2把模板形参指定为double,两种类型的形参不一致,会出错。(针对函数模板)

    作者原版:1.2针对函数模板是正确的,但是忽略了类模板。下面将对类模板的情况进行补充。

    本人添加1.2补充版(针对于类模板)、当我们声明类对象为:A<int> a,比如template<class T>T g(T a, T b){},语句调用a.g(2, 3.2)在编译时不会出错,但会有警告,因为在声明类对象的时候已经将T转换为int类型,而第二个实参3.2把模板形参指定为double,在运行时,会对3.2进行强制类型转换3。当我们声明类的对象为:A<double> a,此时就不会有上述的警告,因为从intdouble是自动类型转换。

    演示示例1:

    TemplateDemo.h

    #ifndef TEMPLATE_DEMO_HXX
    #define TEMPLATE_DEMO_HXX
     
    template<class T> class A{
        public:
            T g(T a,T b);
            A();
    };
     
    #endif

    TemplateDemo.cpp

    #include<iostream.h>
    #include "TemplateDemo.h"
     
    template<class T> A<T>::A(){}
     
    template<class T> T A<T>::g(T a,T b){
        return a+b;
    }
     
    void main(){
        A<int> a;
        cout<<a.g(2,3.2)<<endl;
    }

    编译结果:

    --------------------Configuration: TemplateDemo - Win32 Debug--------------------
    Compiling...
    TemplateDemo.cpp
    G:\C++\CDaima\TemplateDemo\TemplateDemo.cpp(12) : warning C4244: 'argument' : conversion from 'const double' to 'int', possible loss of data
    
    TemplateDemo.obj - 0 error(s), 1 warning(s)

    运行结果: 5 

    我们从上面的测试示例中可以看出,并非作者原作中的那么严密!此处仅是本人跟人测试结果!请大家本着实事求是的态度,自行验证!

    2、非类型形参

    2.1 、非类型模板形参:模板的非类型形参也就是内置类型形参,如template<class T, int a> class B{};其中int a就是非类型的模板形参。

    2.2、 非类型形参在模板定义的内部是常量值,也就是说非类型形参在模板的内部是常量。

    2.3、 非类型模板的形参只能是整型,指针和引用,像double,String, String **这样的类型是不允许的。但是double &,double *,对象的引用或指针是正确的。

    2.4、 调用非类型模板形参的实参必须是一个常量表达式,即他必须能在编译时计算出结果。

    2.5 、注意:任何局部对象,局部变量,局部对象的地址,局部变量的地址都不是一个常量表达式,都不能用作非类型模板形参的实参。全局指针类型,全局变量,全局对象也不是一个常量表达式,不能用作非类型模板形参的实参。

    2.6、 全局变量的地址或引用,全局对象的地址或引用const类型变量是常量表达式,可以用作非类型模板形参的实参

    2.7 、sizeof表达式的结果是一个常量表达式,也能用作非类型模板形参的实参。

    2.8 、当模板的形参是整型时调用该模板时的实参必须是整型的,且在编译期间是常量,比如template <class T, int a> class A{};如果有int b,这时A<int, b> m;将出错,因为b不是常量,如果const int b,这时A<int, b> m;就是正确的,因为这时b是常量。

    2.9 、非类型形参一般不应用于函数模板中,比如有函数模板template<class T, int a> void h(T b){},若使用h(2)调用会出现无法为非类型形参a推演出参数的错误,对这种模板函数可以用显示模板实参来解决,如用h<int, 3>(2)这样就把非类型形参a设置为整数3。显示模板实参在后面介绍。

    2.10、 非类型模板形参的形参和实参间所允许的转换

    1、允许从数组到指针,从函数到指针的转换。如:template <int *a> class A{}; int b[1]; A<b> m;即数组到指针的转换
    2、const修饰符的转换。如:template<const int *a> class A{}; int b; A<&b> m;   即从int *到const int *的转换。
    3、提升转换。如:template<int a> class A{}; const short b=2; A<b> m; 即从short到int 的提升转换
    4、整值转换。如:template<unsigned int a> class A{};   A<3> m; 即从int 到unsigned int的转换。
    5、常规转换。

    非类型形参演示示例1:

    由用户自己亲自指定栈的大小,并实现栈的相关操作。

    TemplateDemo.h

    #ifndef TEMPLATE_DEMO_HXX
    #define TEMPLATE_DEMO_HXX
     
    template<class T,int MAXSIZE> class Stack{//MAXSIZE由用户创建对象时自行设置
        private:
            T elems[MAXSIZE];    // 包含元素的数组
            int numElems;    // 元素的当前总个数
        public:
            Stack();    //构造函数
            void push(T const&);    //压入元素
            void pop();        //弹出元素
            T top() const;    //返回栈顶元素
            bool empty() const{     // 返回栈是否为空
                return numElems == 0;
            }
            bool full() const{    // 返回栈是否已满
                return numElems == MAXSIZE;
            }
    };
     
    template <class T,int MAXSIZE> 
    Stack<T,MAXSIZE>::Stack():numElems(0){     // 初始时栈不含元素
        // 不做任何事情
    }
     
    template <class T,int MAXSIZE>
    void Stack<T, MAXSIZE>::push(T const& elem){
        if(numElems == MAXSIZE){
            throw std::out_of_range("Stack<>::push(): stack is full");
        }
        elems[numElems] = elem;   // 附加元素
        ++numElems;               // 增加元素的个数
    }
     
    template<class T,int MAXSIZE>
    void Stack<T,MAXSIZE>::pop(){
        if (numElems <= 0) {
            throw std::out_of_range("Stack<>::pop(): empty stack");
        }
        --numElems;               // 减少元素的个数
    }
     
    template <class T,int MAXSIZE>
    T Stack<T,MAXSIZE>::top()const{
        if (numElems <= 0) {
            throw std::out_of_range("Stack<>::top(): empty stack");
        }
        return elems[numElems-1];  // 返回最后一个元素
    }
     
    #endif

    TemplateDemo.cpp

    #include<iostream.h>
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include "TemplateDemo.h"
     
    int main(){
        try {
            Stack<int,20>  int20Stack;  // 可以存储20个int元素的栈
            Stack<int,40>  int40Stack;  // 可以存储40个int元素的栈
            Stack<std::string,40> stringStack; // 可存储40个string元素的栈
     
            // 使用可存储20个int元素的栈
            int20Stack.push(7);
            std::cout << int20Stack.top() << std::endl;    //7
            int20Stack.pop();
     
            // 使用可存储40个string的栈
            stringStack.push("hello");
            std::cout << stringStack.top() << std::endl;    //hello
            stringStack.pop();    
            stringStack.pop();    //Exception: Stack<>::pop<>: empty stack
            return 0;
        }
        catch (std::exception const& ex) {
            std::cerr << "Exception: " << ex.what() << std::endl;
            return EXIT_FAILURE;  // 退出程序且有ERROR标记
        }
    }

    非类型形参演示示例2:

    TemplateDemo01.h

    #ifndef TEMPLATE_DEMO_O1
    #define TEMPLATE_DEMO_01
     
    template<typename T> class CompareDemo{
        public:
            int compare(const T&, const T&);
    };
     
    template<typename T> 
    int CompareDemo<T>::compare(const T& a,const T& b){
        if((a-b)>0)
            return 1;
        else if((a-b)<0)
            return -1;
        else
            return 0;
    }
     
    #endif

    TemplateDemo01.cpp

    #include<iostream.h>
    #include "TemplateDemo01.h"
     
    void main(){
        CompareDemo<int> cd;
        cout<<cd.compare(2,3)<<endl;
    }

    运行结果:-1 

    TemplateDemo01.cpp

    #include<iostream.h>
    #include "TemplateDemo01.h"
     
    void main(){
        CompareDemo<double> cd;
        cout<<cd.compare(3.2,3.1)<<endl;
    }

    运行结果: 1 

    TemplateDemo01.h

    #ifndef TEMPLATE_DEMO_O1
    #define TEMPLATE_DEMO_01
     
    template<typename T> class CompareDemo{
        public:
            int compare(T&, T&);
    };
     
    template<typename T> 
    int CompareDemo<T>::compare(T& a,T& b){
        if((a-b)>0)
            return 1;
        else if((a-b)<0)
            return -1;
        else
            return 0;
    }
     
    #endif

    TempalteDemo01.cpp

    #include<iostream.h>
    #include "TemplateDemo01.h"
     
    void main(){
        CompareDemo<int> cd;
        int a=2,b=3;
        cout<<cd.compare(a,b)<<endl;
    }

    非类型形参演示示例3:

    TemplateDemo02.cpp

    #include<iostream.h>
     
    template<typename T>
    const T& max(const T& a,const T& b){
        return a>b ? a:b;
    }
     
    void main(){
        cout<<max(2.1,2.2)<<endl;//模板实参被隐式推演成double
        cout<<max<double>(2.1,2.2)<<endl;//显示指定模板参数。
        cout<<max<int>(2.1,2.2)<<endl;//显示指定的模板参数,会将函数函数直接转换为int。
    }

    运行结果:

    cout<<max<int>(2.1,2.2)<<endl; //显示指定的模板参数,会将函数函数直接转换为int。

    此语句会出现警告:

    --------------------Configuration: TemplateDemo02 - Win32 Debug--------------------
    Compiling...
    TemplateDemo02.cpp
    G:\C++\CDaima\TemplateDemo02\TemplateDemo02.cpp(11) : 
      warning C4244: 'argument' : conversion from 'const double' to 'const int', possible loss of data
    G:\C++\CDaima\TemplateDemo02\TemplateDemo02.cpp(11) : 
      warning C4244: 'argument' : conversion from 'const double' to 'const int', possible loss of data
    
    TemplateDemo02.obj - 0 error(s), 2 warning(s)
    
    更多相关内容
  • HbaseTemplate 操作hbase

    热门讨论 2015-04-10 09:58:38
    java 利用 sping-data-hadoop HbaseTemplate 操作hbase find get execute 等方法 可以直接运行
  • template.js源码下载

    2014-10-14 18:19:30
    轻松使用js拼接html, jsTemplate帮助你轻松搞定,不用再为js拼接html字符串苦恼了。
  • 文章目录一,consul概述二,consul-template概述三,regisrator的作用四,搭建consul集群环境1.安装Consul2.配置容器服务自动加入nginx集群3.安装consul-template4.准备template nginx模板文件5.部署nginx6.启动 ...

    一,consul概述

    1.什么是consul

    Consul是HashiCorp公司推出的开源工具,Consul由Go语言开发,部署起来非常容易,只需要极少的可执行程序和配置文件,具有绿色、轻量级的特点。
    Consul是分布式的、高可用的、可横向扩展的用于实现分布式系统的服务发现与配置。

    2.Consul的作用

    • 服务注册与发现(主要功能),提供HTTP和DNS两种发现方式
    • 健康检查,支持多种协议,HTTP、TCP等
    • Key/Value存储
    • 支持多数据中心
    • 基于Golong语言,可移植性强
    • 支持ACL访问控制
    • 与Docker等轻量级容器可无缝配合

    二,consul-template概述

    Consul-Template是一个守护进程,用于实时查询Consul集群信息

    Consul-Template可以更新文件系统上任意数量的指定模板,生成配置文件更新完成以后,可以选择运行shell命令执行更新操作,重新加载Nginx。

    Consul-Template可以查询Consul中的服务目录、Key、Key-values等。
    这种强大的抽象功能和查询语言模板可以使Consul-Template特别适合动态的创建配置文件。

    例如:创建Apache/Nginx Proxy Balancers、Haproxy Backends

    三,regisrator的作用

    一个由Go语言编写的,针对docker使用的,可以用于检测容器状态自动注册和注销docker容器的服务到服务配置中心。目前支持Consul、Etcd和SkyDNS2。

    四,搭建consul集群环境

    架构图如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8S6NZpWZ-1647749284653)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\1.bmp)]

    主机操作系统ip所需软件
    consulcentos7192.168.100.135Docker 、Consul、Consul-template
    registratorCentos 7192.168.100.142Docker、registrator

    需求:

    实现单机网络下容器与容器之间互通

    使用Docker Compose创建容器

    搭建Consul服务实现自动发现和更新

    环境准备:关闭防火墙和selinux

    systemctl stop firewalld
    setenforce 0 
    

    1.安装Consul

    consul:192.168.100.135

    编译安装consul

    mkdir /root/consul
    cd /root/consul
    unzip consul_0.9.2_linux_amd64.zip
    mv consul /usr/local/bin/
    
    
    //设置代理,在后台启动 consul 服务端
    consul agent \     
    -server \
    -bootstrap \
    -ui \
    -data-dir=/var/lib/consul-data \
    -bind=192.168.80.15 \
    -client=0.0.0.0 \
    -node=consul-server01 &> /var/log/consul.log &
    ##############解释####################
    
    //设置代理,在后台启动 consul 服务端
    consul agent \:启动consul集群
    
    -server \: 以server身份启动。默认是client。
    
    -bootstrap \:用来控制一个server是否在bootstrap模式,在一个数据中心中只能有一个server处于bootstrap模式,当一个server处于 bootstrap模式时,可以自己选举为 server-leader。
    
    -ui \:指定开启 UI 界面,这样可以通过 http://localhost:8500/ui 这样的地址访问 consul 自带的 web UI 界面。
    
    -data-dir=/var/lib/consul-data \:指定数据存储目录。
    
    -bind=192.168.80.15 \:指定用来在集群内部的通讯地址,集群内的所有节点到此地址都必须是可达的,默认是0.0.0.0。
    
    -client=0.0.0.0 \:指定 consul 绑定在哪个 client 地址上,这个地址提供 HTTP、DNS、RPC 等服务,默认是 127.0.0.1。
    
    -node=consul-server01 &> /var/log/consul.log & :节点在集群中的名称,在一个集群中必须是唯一的,默认是该节点的主机名。指定数据中心名称,默认是dc1。
    
    
    [root@bogon consul]# consul members
    
    [root@bogon consul]# consul info | grep leader
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P8BHx4Hn-1647749284654)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\2.bmp)]

    通过 http api获取集群信息

    curl 127.0.0.1:8500/v1/status/peers       //查看集群server成员
    curl 127.0.0.1:8500/v1/status/leader      //集群Raf leader
    curl 127.0.0.1:8500/v1/catalog/services   //注册的所有服务
    curl 127.0.0.1:8500/v1/catalog/nginx      //查看nginx服务信息
    curl 127.0.0.1:8500/v1/catalog/nodes      //集群节点详细信息
    
    netstat -natp |grep consul
    这5个端口的作用:
    8300:集群内数据的读写和复制
    8301:单个数据中心gossip协议通讯
    8302:跨数据中心gossip协议通讯
    8500:提供获取服务列表、注册服务、注销服务等HTTP接口;提供UI服务
    8600:采用DNS协议提供服务发现功能
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ne3VcbDw-1647749284655)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\3.bmp)]

    2.配置容器服务自动加入nginx集群

    registrator:192.168.100.142

    (1)安装Gliderlabs/Registrator

    docker run -d \
    --name=registrator \
    --net=host \
    -v /var/run/docker.sock:/tmp/docker.sock \
    --restart=always \
    gliderlabs/registrator:latest \
    --ip=192.168.100.142 \
    consul://192.168.100.135:8500
    
    -------------------------------------------------------------
    --net=host :把运行的docker容器设定为host网络模式。
    -v /var/run/docker.sock:/tmp/docker.sock :把宿主机的Docker守护进程(Docker daemon)默认监听的Unix域套接字挂载到容器中。
    --restart=always :设置在容器退出时总是重启容器。
    --ip :刚才把network指定了host模式,所以我们指定ip为宿主机的ip。
    consul :指定consul服务器的IP和端口。
    -------------------------------------------------------------
    

    (2) 测试服务发现功能是否正常 创建四个容器

    docker run -itd -p:83:80 --name test-01 -h test01 nginx
    docker run -itd -p:84:80 --name test-02 -h test02 nginx
    docker run -itd -p:88:80 --name test-03 -h test03 httpd
    docker run -itd -p:89:80 --name test-04 -h test04 httpd	
    
    docker ps -a
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gu2Z3KER-1647749284656)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\4.bmp)]

    (3)验证http和nginx服务是否注册到 consul

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AimsUbJ8-1647749284657)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\5.bmp)]

    在consul服务器使用curl测试连接服务器

    curl 127.0.0.1:8500/v1/catalog/services 
    {"consul":[],"httpd":[],"nginx":[]}
    

    3.安装consul-template

    (1).准备 template nginx 模板文件
    在consul服务器上操作(192.168.100.135)

    unzip consul-template_0.19.3_linux_amd64.zip 
    mv consul-template /usr/bin/
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SxxhB2zm-1647749284658)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\7.bmp)]

    4.准备template nginx模板文件

    vim /root/consul/nginx.ctmpl
    
    upstream http_backend {
      {{range service "nginx"}}
       server {{.Address}}:{{.Port}};
       {{end}} 
    }
    
    
    server {
        listen 8000;
        server_name localhost 192.168.100.135;
        access_log /var/log/nginx/kgc.com-access.log;
        index index.html index.php;
        location / {
            proxy_set_header HOST $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Client-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://http_backend;
        }
    }
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0YdxF76-1647749284659)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\8.bmp)]

    5.部署nginx

    在consul服务器上操作(192.168.100.135)

    我这里就yum安装nginx了

    创建nginx yum仓库文件

    vim /etc/yum.repos.d/nginx.repo
    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/7/$basearch/
    gpgcheck=0
    enabled=1
    
    
    yum install nginx -y 
    nginx -v
    
    systemctl start nginx
    systemctl enable nginx
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N7GNxXsG-1647749284660)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\9.bmp)]

    6.启动 template

     consul-template --consul-addr 192.168.100.135:8500 \
    > --template "/root/consul/nginx.ctmpl:/etc/nginx/conf.d/kgc.conf:/usr/sbin/nginx -s reload"
    > --log-level=info
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cfwBLcZx-1647749284661)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\10.bmp)]

    重开一个consul终端,查看生成的配置文件

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iCZQOW1M-1647749284661)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\11.bmp)]

    7.访问 template-nginx

    在这里插入图片描述

    root@test01:/# echo "this is test1 web" > /usr/share/nginx/html/index.html
    root@test01:/# exit
    exit
    [root@zqh ~]# docker exec -it c4dc60f51fdb bash
    root@test02:/# echo "this is test2 web" > /usr/share/nginx/html/index.html 
    root@test02:/# exit
    exit
    

    浏览器访问 http://[192.168.100.135:8000并不断刷新

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3VdW3mSL-1647749284663)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\13.bmp)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rkXWQwbu-1647749284663)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\14.bmp)]

    8.增加一个nginx容器节点

    (1)增加一个 nginx 容器节点,测试服务发现及配置更新功能。

    docker run -itd -p:85:80 --name test-05 -h test05 nginx
    

    观察 template 服务,会从模板更新/usr/local/nginx/conf/vhost/kgc.conf 文件内容,并且重载 nginx 服务

    (2)查看/usr/local/nginx/conf/vhost/kgc.conf 文件内容

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DlrtTdEe-1647749284664)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\15.bmp)]

    9.consul多节点

    (1)开一台新的机器(192.168.100.140)加入到已有的群集中

    要先安装 consul

    运行consul

    consul agent \
    -server \
    -ui \
    -data-dir=/var/lib/consul-data \
    -bind=192.168.100.140 \
    -client=0.0.0.0 \
    -node=consul-server02 \
    -enable-script-checks=true  \
    -datacenter=dc1  \
    -join 192.168.100.135 &> /var/log/consul.log &
    
    -enable-script-checks=true :设置检查服务为可用
    -datacenter : 数据中心名称
    -join :加入到已有的集群中
    

    切换到consul服务器上操作(192.168.100.135)

    consul members
    consul operator raft list-peers
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IZo0hx3g-1647749284664)(C:\Users\zhuquanhao\Desktop\截图命令集合\linux\Docker\consul-template\16.bmp)]

    展开全文
  • Spring Boot 项目,在 Spring Tool Suite 4, Version: 4.4.0.RELEASE 运行没有问题,将项目中的静态资源和页面复制到 IDEA 的项目中,除了 IDE ...Exception processing template "index": An error happened durin...

    Spring Boot 项目,在 Spring Tool Suite 4, Version: 4.4.0.RELEASE 运行没有问题,将项目中的静态资源和页面复制到 IDEA 的项目中,除了 IDE 不同,其他基本相同。

    运行 IDEA 中的项目,然后访问,出现异常:

    Exception processing template "index": An error happened during template parsing (template: "class path resource [templates/index.html]")
    

    具体异常:

      1 2019-12-10 21:37:40.896 ERROR 10276 --- [nio-8081-exec-1] org.thymeleaf.TemplateEngine             : [THYMELEAF][http-nio-8081-exec-1] Exception processing template "index": An error happened during template parsing (template: "class path resource [templates/index.html]")
      2 
      3 org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/index.html]")
      4     at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
      5     at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
      6     at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
      7     at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
      8     at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
      9     at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
     10     at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
     11     at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373)
     12     at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1118)
     13     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057)
     14     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
     15     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
     16     at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
     17     at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
     18     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
     19     at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
     20     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
     21     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
     22     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
     23     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
     24     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
     25     at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
     26     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
     27     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
     28     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
     29     at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
     30     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
     31     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
     32     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
     33     at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
     34     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
     35     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
     36     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
     37     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
     38     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
     39     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
     40     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
     41     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
     42     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
     43     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
     44     at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)
     45     at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
     46     at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
     47     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591)
     48     at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
     49     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
     50     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
     51     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
     52     at java.lang.Thread.run(Thread.java:748)
     53 Caused by: org.attoparser.ParseException: Error resolving template [_fragment], template might not exist or might not be accessible by any of the configured Template Resolvers (template: "index" - line 3, col 11)
     54     at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
     55     at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
     56     at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
     57     ... 48 common frames omitted
     58 Caused by: org.thymeleaf.exceptions.TemplateInputException: Error resolving template [_fragment], template might not exist or might not be accessible by any of the configured Template Resolvers (template: "index" - line 3, col 11)
     59     at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869)
     60     at org.thymeleaf.engine.TemplateManager.parseStandalone(TemplateManager.java:250)
     61     at org.thymeleaf.standard.expression.FragmentExpression.resolveExecutedFragmentExpression(FragmentExpression.java:588)
     62     at org.thymeleaf.standard.processor.AbstractStandardFragmentInsertionTagProcessor.computeFragment(AbstractStandardFragmentInsertionTagProcessor.java:379)
     63     at org.thymeleaf.standard.processor.AbstractStandardFragmentInsertionTagProcessor.doProcess(AbstractStandardFragmentInsertionTagProcessor.java:110)
     64     at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
     65     at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
     66     at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
     67     at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314)
     68     at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleOpenElementEnd(TemplateHandlerAdapterMarkupHandler.java:304)
     69     at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:278)
     70     at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleOpenElementEnd(OutputExpressionInlinePreProcessorHandler.java:186)
     71     at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:124)
     72     at org.attoparser.HtmlElement.handleOpenElementEnd(HtmlElement.java:109)
     73     at org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297)
     74     at org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402)
     75     at org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159)
     76     at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710)
     77     at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)
     78     ... 50 common frames omitted
     79 
     80 2019-12-10 21:37:40.900 ERROR 10276 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/index.html]")] with root cause
     81 
     82 org.thymeleaf.exceptions.TemplateInputException: Error resolving template [_fragment], template might not exist or might not be accessible by any of the configured Template Resolvers (template: "index" - line 3, col 11)
     83     at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869)
     84     at org.thymeleaf.engine.TemplateManager.parseStandalone(TemplateManager.java:250)
     85     at org.thymeleaf.standard.expression.FragmentExpression.resolveExecutedFragmentExpression(FragmentExpression.java:588)
     86     at org.thymeleaf.standard.processor.AbstractStandardFragmentInsertionTagProcessor.computeFragment(AbstractStandardFragmentInsertionTagProcessor.java:379)
     87     at org.thymeleaf.standard.processor.AbstractStandardFragmentInsertionTagProcessor.doProcess(AbstractStandardFragmentInsertionTagProcessor.java:110)
     88     at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
     89     at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
     90     at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
     91     at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314)
     92     at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleOpenElementEnd(TemplateHandlerAdapterMarkupHandler.java:304)
     93     at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:278)
     94     at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleOpenElementEnd(OutputExpressionInlinePreProcessorHandler.java:186)
     95     at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:124)
     96     at org.attoparser.HtmlElement.handleOpenElementEnd(HtmlElement.java:109)
     97     at org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297)
     98     at org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402)
     99     at org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159)
    100     at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710)
    101     at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)
    102     at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
    103     at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
    104     at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
    105     at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
    106     at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
    107     at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
    108     at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
    109     at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
    110     at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373)
    111     at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1118)
    112     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057)
    113     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    114     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    115     at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    116     at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    117     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    118     at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    119     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    120     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    121     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    122     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    123     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    124     at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    125     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    126     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    127     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    128     at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    129     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    130     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    131     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    132     at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    133     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    134     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    135     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    136     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    137     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    138     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
    139     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    140     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    141     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    142     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    143     at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)
    144     at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    145     at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
    146     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591)
    147     at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    148     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    149     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    150     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    151     at java.lang.Thread.run(Thread.java:748)
    

    起初是直接运行项目,即 Shift + F10:

    后来重新编译项目,再访问,就没有出现异常:

    展开全文
  • art-template踩坑

    千次阅读 2019-03-11 21:52:56
    art-template使用笔记 art-template 是前端的一个高性能 JavaScript 模板引擎,它采用作用域预声明的技术来优化模板渲染速度,从而获得接近 JavaScript 极限的运行性能。 通过下面一张图可以大致了解下 art-template...

    art-template使用笔记

    art-template 是前端的一个高性能 JavaScript 模板引擎,它采用作用域预声明的技术来优化模板渲染速度,从而获得接近 JavaScript 极限的运行性能。

    通过下面一张图可以大致了解下 art-template 与其他方式渲染HTML页面的性能比较:

    性能

    具体跟 Vue、React 这些前端主流框架比较的性能,官方并未给出数据,但是我认为只比较页面渲染能力的话,应该相差不多, Vue、React 是一整套的前端解决方案,而 art-template 只是一个 js模板引擎,二者定位和功能不同,不做详细比较,猜测 art-template 同样是使用虚拟 DOM 的方式进行页面渲染,否则能达到这样的性能,着实不容易。就学习而言,如果学习过 Vue、React,学这个非常简单,反过来学会 art-template 对学习 Vue、React也有一定帮助。

    在网上查询资料的时候,发现 art-template 好像是腾讯团队开发开源的,了解到这个情况的时候,心中少不了吐槽,不可否认东西确实好用,但是架不住腾讯团队写的文档烂啊!!腾讯团队什么时候能在文档上面长点心,学学隔壁的阿里。废话不多说了,简单写下容易遇到的问题。

    初始化问题

    关于 art-template 模板编写语法很简洁; template 对象的初始化也非常简单,只有两行代码,

    模板编写:

    <script id="art-template" type="text/html">
    <table>
       /******/
        <tbody>
            {{each classInfoList}}
            <tr>
                <td>{{$index+1}}</td>
                <td>{{$value.Id}}</td>
                <td>{{$value.Name}}</td>
                <td>{{$value.Teacher}}</td>
                <td>{{$value.Remark}}</td>
                <td>
                    <a href="{{$value.Uri}}">删除</a>
                </td>
            </tr>
            {{/each}}
        </tbody>
    </table>
    </script>
    

    template对象初始化:

    var html = template("art-template", datas);
    document.getElementById('app').innerHTML = html;
    
    • "art-template" 是定义好的模板的 id
    • datas 是需要渲染的数据

    JS执行时间、顺序问题

    在网上找到的 Demo 大多都是在 js 里面写一个假数据,用定义好的数据去初始化 template 对象,例如:

    <!DOCTYPE HTML> 
    <html> 
    <head> 
    <meta charset="UTF-8"> 
    <title>basic-demo</title> 
    <script src="../dist/template.js"></script> 
    </head> 
    <body> 
    <div id="content"></div> 
    <script id="test" type="text/html"> 
    {{if isAdmin}} 
    <h1>{{title}}</h1> 
    <ul> 
     {{each list as value i}} 
      <li>索引 {{i + 1}}{{value}}</li> 
     {{/each}} 
    </ul> 
    {{/if}} 
    </script> 
    <script> 
    var data = { 
     title: '基本例子', 
     isAdmin: true, 
     list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他'] 
    }; 
    var html = template('test', data); 
    document.getElementById('content').innerHTML = html; 
    </script> 
    </body> 
    </html>
    

    因为以前主要使用 Vue ,Vue 是有动态渲染,但是忘记了这个并没有提到是动态渲染,同时项目开发时,数据大多通过 Ajax 从后台获取,因此在开始时,将 template 对象初始化放在了 ajax 回调函数外,因为 ajax 请求数据需要花费时间,同时js代码跟后台代码执行顺序不同,并不是按行数依次执行,所以前期导致一直渲染失败。应注意 js 代码执行顺序和执行时间的问题。

    完整ajax代码如下:

    var datas = {
        title: "",
        classInfoList: []
    }
    $.ajax({
        type: "GET",
        dataType:"JSON",
        url: "/ClassHandler.ashx",
        success: function (data) {
            //原生JS序列化JSOn
            //datas.classInfoList = JSON.parse(data).classInfoList;
            datas.classInfoList = data.classInfoList;
            datas.title =data.title;
            html = template("art-template", datas);
            document.getElementById('app').innerHTML = html;
        }
    })
    

    template数据初始化问题

    在上面也看到,序列化 template 对象一共传了两个参数,一个是模板的 Id,另外一个是数据。

    但是这个数据有个一问题,如果返回回来的 JSON 数据是类似数组数据的话,是没有办法直接渲染的,如:

     [{
    		"Id": 0,
    		"Name": "班级0",
    		"Teacher": "教师0",
    		"Remark": "这是班级0的简介",
    		"Uri": "/deleteClass.ashx?id=0"
    	}, {
    		"Id": 1,
    		"Name": "班级1",
    		"Teacher": "教师1",
    		"Remark": "这是班级1的简介",
    		"Uri": "/deleteClass.ashx?id=1"
    	}, {
    		"Id": 2,
    		"Name": "班级2",
    		"Teacher": "教师2",
    		"Remark": "这是班级2的简介",
    		"Uri": "/deleteClass.ashx?id=2"
    	}]
    

    这个样子是没有办法直接进行渲染,需要对数据如上述代码块包装,才能正常渲染。

    如果返回 JSON 数据为:

    {
    	"classInfoList": [{
    		"Id": 0,
    		"Name": "班级0",
    		"Teacher": "教师0",
    		"Remark": "这是班级0的简介",
    		"Uri": "/deleteClass.ashx?id=0"
    	}, {
    		"Id": 1,
    		"Name": "班级1",
    		"Teacher": "教师1",
    		"Remark": "这是班级1的简介",
    		"Uri": "/deleteClass.ashx?id=1"
    	}, {
    		"Id": 2,
    		"Name": "班级2",
    		"Teacher": "教师2",
    		"Remark": "这是班级2的简介",
    		"Uri": "/deleteClass.ashx?id=2"
    	}],
    	"title": "软件学院班级列表"
    }
    

    可以直接初始化 template 对象,并进行渲染(模板不变)

    <script>
        $.ajax({
            type: "GET",
            dataType:"JSON",
            url: "/ClassHandler.ashx",
            success: function (data) {
                html = template("art-template", data);
                document.getElementById('app').innerHTML = html;
            }
        })
    </script>
    

    template 对象初始化需注意地方

    API: template(filename, content)

    根据模板名渲染模板。

    • 参数:
      • {string} filename
      • {Object,string} content
    • 返回值:
      • 如果 contentObject,则渲染模板并返回 string
      • 如果 contentstring,则编译模板并返回 function

    浏览器版本无法加载外部文件,filename 为存放模板的元素 id

    因为渲染的时候,数据大多从后台获取,后台返回的数据可能为字符串或JSON,如果第二个参数(content)传进来的是字符串的话,没有报错,但是渲染会失败,渲染结果如下:

    在这里插入图片描述

    因此,需注意 template 初始化赋值时,数据格式是否正确。

    渲染问题

    each 循环渲染问题

    关于循环的语法,官方文档上写的很简洁:

    image

    默认在遍历 target 时,有两个值,value和index,其中 value 是单个对象值,index 是下标。

    根据文档所写,我把

    {{each classInfoList}}
            <tr>
                <td>{{$index+1}}</td>
                <td>{{$value.Id}}</td>
                <td>{{$value.Name}}</td>
                <td>{{$value.Teacher}}</td>
                <td>{{$value.Remark}}</td>
                <td>
                    <a href="{{$value.Uri}}">删除</a>
                </td>
            </tr>
    {{/each}}
    

    修改为:

    {{each classInfoList val key}}
            <tr>
                <td>{{$key+1}}</td>
                <td>{{$val.Id}}</td>
                <td>{{$val.Name}}</td>
                <td>{{$val.Teacher}}</td>
                <td>{{$val.Remark}}</td>
                <td>
                    <a href="{{$val.Uri}}">删除</a>
                </td>
            </tr>
    {{/each}}
    

    浏览器在渲染的时候就报错了:
    在这里插入图片描述
    至今不清楚,是我没领会文档说明,还是 art-template 团队忘了维护文档了。

    结语

    本文只是 art-template js模板引擎的简单使用,还有其他几个接口、方式没有逐一介绍,在我看来这些已经能够满足基本的开发使用,至于更加复杂的渲染、渲染切换,Vue 比 art-template 省心。如有兴趣继续研究 art-template ,附上官方文档及参考博客链接。


    参考文档:

    展开全文
  • 关于MongoTemplate的使用

    千次阅读 2021-10-24 15:31:23
    关于MongoTemplate的使用1 MongoTemplate使用1 添加maven依赖2 添加连接配置信息3 实体类4 MongoTemplate的操作5 业务处理类6 总结 因未接触MongoDB数据库,而项目中使用MongoDB做数据库, 且选择Spring整合的Mongo...
  • MongoTemplate入门

    万次阅读 2018-09-11 09:57:45
    MongoTemplate mongoTemplate; /** * 创建索引 * 只包含单键和复合索引 * * @param collectionName 集合名称 * @param fieldName 字段名称 */ public void ensureIndex (String collectionName...
  • mongoTemplate 常见操作

    万次阅读 2021-09-28 08:48:19
     mongodbTemplate中还有另外一个更新方法: mongoTemplate.updateFirest(query, update, "class"); mongoTemplate.updateMulti(query, update, "class"); 这个两个方法一个是更新满足条件的第一条数据,一个是更新...
  • MongoTemplate增删改查,分页查询,去重查询,全表删除
  • 今天继续给大家介绍Linux运维相关知识,本文主要内容是Ansible的Template模板的高级控制。 一、Ansible Template 之when语句 二、Ansible Template 之for语句 三、Ansible Template 之for if语句
  • 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符串,用于传递到前端 STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'}, STUDENT_LIST...
  • Flask 中的渲染方法有两种 : render_template() 和 render_template_string() render_template() 函数 渲染一个指定的文件 , 这个指定的文件其实就是模板 模板中代码 <!DOCTYPE html> <...
  • MongoTemplate基本使用

    千次阅读 2021-12-31 15:06:38
    MongoTemplate基本使用 一、普通查询操作 1.is查询 Query query = new Query(); // where...is... 相当于 where ? = ? query.addCriteria(Criteria.where("数据库字段名").is("你的参数")); // findOne 返回的是一个...
  • mongoTemplate的分页,分组,统计

    万次阅读 2019-07-10 10:22:38
    crud参考:... mongoTemplate的分页,分组,统计以及聚合Aggregation和mapReduce的使用 package com.star.ac.mongodb.impl; import java.util.ArrayList; import java....
  • template(模板)的介绍以及使用方法

    千次阅读 2022-03-02 17:44:03
    函数模板的格式: template 返回值类型 函数名(参数列表){} template<typename T>//此语句也可以为template void Swap( T& left, T& right) { T temp = left; left = right; right = temp; } 函数模板的原理...
  • Vue Template Explorer

    千次阅读 2022-03-11 10:09:29
    Vue Templata Explorer vue2地址路径:https://template-explorer.vuejs.org/# vue3地址路径:https://vue-next-template-explorer.netlify.app/#
  • template的用法(超详细)

    千次阅读 2021-10-05 15:57:14
    假如我们有以下函数 int compare(const string &v1,const string &v2) { if(v1<v2)return -1; if(v1>...template<typename T> int compare(const T&v1,const T&v2) {
  • art-template是由腾讯出品的一款比较流行的模板引擎,易上手 art-template官网 atr-template文档 1.1 以前的项目存在的问题 数据和HTML标字符串拼接导致,代码混乱,拼接容易出错,不易维护 业务逻辑和数据界面...
  • Template模板方法的使用

    千次阅读 2020-09-03 13:15:19
    该方法的核心思想就是将json数据传入按照art-template模板编写模板中去。 1> 引入js文件 <script src="./js/template-web.js" type="text/javascript" charset="utf-8"></script> 2> 准备json...
  • https://www.cnblogs.com/duanxz/p/9734597.html ... consul-template + nginx部署高可用负载均衡 一、Consul-Template简介 Consul-Template是基于Consul的自动替换配置文件的应用。在Consul-Temp...
  • 关于template标签用法总结(含vue中的用法总结)

    万次阅读 多人点赞 2019-09-02 20:31:11
    文章目录html5中的template标签template标签操作的属性和方法vue中的template html5中的template标签 html中的template标签中的内容在页面中不会显示。但是在后台查看页面DOM结构存在template标签。这是因为template...
  • Looking for Laravel Vue admin template free? Then here is the best collection for you. Well,Laravelis a free, open-source ...
  • 【Vue】template 模板用法

    万次阅读 2021-03-30 11:52:48
    template标签:其内容隐藏在客户端之外 该内容在加载页面是不会呈现,不会渲染出任何信息 相当于自带属性:template {display: none;} <body> <template> <!-- 该标签内容是不可见的 --> ...
  • VUE3(template使用)

    千次阅读 2021-08-17 18:08:22
    模板template就是定义vue时指定页面的结构构成 默认使用mount('选择器')指定挂在元素的内容来构建页面模板 可以使用template独立的来定义页面模板,此时挂在元素的内容将被忽略 <!DOCTYPE html> <...
  • pgsql之template1 和 template0

    千次阅读 2019-10-29 15:56:01
    template1和template0是pgsql的模板数据库。所谓模板数据库就是创建新database时,PostgreSQL会基于模板数据库制作一份副本,其中会包含所有的数据库设置和数据文件。PostgreSQL安装好以后会默认附带两个模板数据库...
  • golang模板(text/template)

    万次阅读 2019-04-08 10:57:03
    text/template是Go语言标准库,实现数据驱动模板以生成文本输出,可以理解为一组文字按照特定格式动态嵌入另一组文字中。 还有个处理html文字的模板(html/template),感兴趣的可以了解下。 简单字符 示例 package ...
  • 错误信息:Exception processing template “/view/df”: Error resolving template “/view/df”, template might not exist or might not be accessible by any of the configured Template Resolvers org....
  • template的使用

    千次阅读 2020-05-17 22:45:57
    1、template的使用 C++ 的高级玩法,当然包含了模板。模板(template)是实现代码重用机制的一种工具,它可以实现类型参数化,把类型定义为参数(模板...
  • grid-template-columns / grid-template-rows 使用空格分隔的值列表,用来定义网格的 列 和 行。 值表示 网格轨道(Grid Track) 大小,值之间的空格 表示网格线。 .container { grid-template-columns: <track-...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,641,583
精华内容 656,633
关键字:

template