<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          前端模板引擎jsrender的實用入門教程

          時間:?2017-11-15閱讀:?3816標簽:?模板作者:?木白no1

          jsrender官網號稱簡單直觀、強大輕快可擴展。壓縮體積也只有8.9kb,可以單獨在瀏覽器或node中使用,也可以配合jQuery使用。

          jsrender使用 {{}} 來做分界,如果{{}}與你現有的模板引擎沖突你可以使用api來自定義,比如:

          $.views.settings.delimiters("<%", "%>");
          
          //原本
          <p>{{:name}}</p>
          //修改后
          <p><%:name%></p>


          一、基本語法


          1. 基本變量標簽 {{:name}}

          基本變量需要使用冒號 ":" 作為標識,一般是簡單對象的某個屬性。比如傳入一個簡單對象data

          //模板
          <script type="text/x-jsrender" id="j-specCard">
             <table>
                 <tr>
                     <td>Name: {{:name}}</td>
                     <td>Age: {{:age}}</td>
                 </tr>
             </table>
          </script>
          //邏輯
          (function(jq, g) {
          //傳入一個簡單對象
              var data = {
                      'name': 'alice',
                      'age': 18
                  },
                  //獲取模板
                  jsRenderTpl = $.templates('#j-specCard'),
                  //末班與數據結合
                  finalTpl = jsRenderTpl(data);
          
              $('.box').html(finalTpl);
          })(jQuery, window);

          //傳入一個多層級對象complexData

          <body>
              <div></div>
              <script type="text/x-jsrender" id="j-specCard">
                  <table>
                      <tr>
                          <td>Name: {{:personalInfo.name}}</td>
                          <td>Age: {{:personalInfo.age}}</td>
                      </tr>
                  </table>
                  <p>{{:top.middle1}}</p>
                  <p>{{:top.middle.bottom}}</p>
              </script>
          </body>
          <script src="../lib/jquery-1.11.2.min.js"></script>
          <script src="../lib/jsrender.js"></script>
          <script>
          (function(jq, g) {
          
              var complexData = {
                      'personalInfo': {
                          'name': 'alice',
                          'age': 18
                      },
                      'top': {
                          'middle': {
                              'bottom': 'this is bottom value'
                          },
                          'middle1': 'this is middle1 value'
                      }
                  },
                  //獲取模板
                  jsRenderTpl = $.templates('#j-specCard'),
                  //末班與數據結合
                  finalTpl = jsRenderTpl(complexData);
          
              $('.box').html(finalTpl);
          })(jQuery, window)
          </script>

          如上所見,不管傳入的對象有多復雜,都能按照層級去到屬性,只是把最外層的對象名省略掉了。


          2. 對基本變量有轉譯功能標簽{{>name}}

          轉譯功能標簽使用大于號 ">" 作為標識,可以讓數據原樣輸出,可以防止注入攻擊。比如 

          <body>
              <div></div>
              <script type="text/x-jsrender" id="j-specCard">
                  <p>{{:name}}</p>
                  <p>{{>name}}</p>
              </script>
          </body>
          <script src="../lib/jquery-1.11.2.min.js"></script>
          <script src="../lib/jsrender.js"></script>
          <script>
          (function(jq, g) {
          
              var data = {
                      'name': '<b>i am alice</b><script>alert("我是注入腳本攻擊")<\/script>'
                  },
                  //獲取模板
                  jsRenderTpl = $.templates('#j-specCard'),
                  //末班與數據結合
                  finalTpl = jsRenderTpl(data);
          
              $('.box').html(finalTpl);
          
          })(jQuery, window)
          </script>

          Paste_Image.png


          雖然{{>}}有轉譯功能,我們不一定必須用他,因為有些標簽我們還是需要顯示的,視具體情況而定


          3. 啟用與定義全局變量的標簽{{*}}與 {{*:}},不支持代碼語法,如果是代碼,那么會咦字符串的形式輸出

          在jsrender語法中,不僅可以處理簡單的對象,也支持表達式,比如

          <p>{{*:name.firstName + '  ' + name.lastName </p>
           var data = {
                  'name': {
                      'firstName': 'cury',
                      'lastName': 'steven'
                  }
              }

          但是為了保證封裝性,并不是任何表達式都可以處理的,比如全局變量window就不行。比如

          <p>{{:name.firstName + '  ' + name.lastName + '  ' + window.describe}}</p>
          window.describe = " he is a basketball player";

          這樣的代碼會報錯的 Uncaught TypeError: Cannot read property 'describe' of undefined。即使這樣,jsrender給我提供了手動開啟的方式,只需要調用api,并且使用{{*:}}標簽就可以使用了。比如

          <body>
              <div></div>
              <script type="text/x-jsrender" id="j-specCard">
              <!--除了可以在js中定義全局變量,在模板中也是可以的-->
                  {{* window.count = 1}}
                  <p>{{*:count + 2}}</p>
                  <p>{{:name.firstName + '  ' + name.lastName + '  ' + window.describe}}</p>
                  <!-- <p>{{*:describe + '  ' + name + count}}</p> -->
              </script>
          </body>
          <script src="../lib/jquery-1.11.2.min.js"></script>
          <script src="../lib/jsrender.js"></script>
          <script>
          (function(jq, g) {
          
              window.describe = " he is a basketball player";
          
              $.views.settings.allowCode(true);
              var data = {
                  'name': {
                      'firstName': 'cury',
                      'lastName': 'steven'
                  }
              },
                  //獲取模板
                  jsRenderTpl = $.templates('#j-specCard'),
                  //末班與數據結合
                  finalTpl = jsRenderTpl(data);
          
              $('.box').html(finalTpl);
          
          })(jQuery, window)
          </script>

          首先需要執行$.views.settings.allowCode(true);,把設置開啟,然后使用{{* window.count = 1}}定義一個變量,然后再用{{*:count}}引用變量。當然,jsrender也提供了只有某一個模板支持全局變量的設置方式

          var tmpl = $.templates({
              markup: "#myTemplate",
              allowCode: true
            });


          4. 注釋的標簽 {{!-- --}}

          在jsrender模板中,html的注釋<!-- -->是不起作用的,jsrender會原樣的輸出到dom節點中,而dom中是認識<!-- -->這個注釋的,所以并不會顯示。但是呢,如果注釋中有未定義的變量,那么jsrender就會報錯,比如

           <script type="text/x-jsrender" id="j-specCard">
                  <p>這是jsrender模板</p>
                  <!-- <p>{{*:describe + '  ' + name + count}}</p> -->
              </script>

          如果我沒有定義window.describe 跟window.count變量,那么這段代碼就會報錯,所以我們在jsrender模板中要使用jsrender的注釋{{!-- --}},而且jsrender在渲染的時候是不會把注釋代碼返回的。


          5. 條件判斷語句 {{if}} {{else}}

          jsrender 的if else 語法跟正常的代碼邏輯還是有點區別的,當只有兩種情況的時候,是沒有區別的,就是if else

          <script type="text/x-jsrender" id="j-specCard">
              {{if name == 'alice'}}
              <p>Hello Alice</p>
              {{else}}
              <p>Hello tourisor</p>
              {{/if}}
          </script>

          但是當有多種情況的時候,也就是if elseif elseif else的時候,可是jsrender并沒有elseif這樣的寫法,它會根據情況來判斷,如果是多重情況,它會自動把else 當做elseif來使用

          <script type="text/x-jsrender" id="j-specCard">
              {{if count == 1}}
                  <p>welcome first!</p>
              {{else count == 2}}
                  <p>welcome again</p>
                  <p>這里的else會被當做elseif count==2 使用</p>
              {{else}}
                  <p>welcom back!</p>
              {{/if}}
          </script>

          if else 除了以{{if}}....{{/if}}block閉合的形式使用,也可以使用{{if xxx=true ... /}}自閉合的形式,而且還可以引入模板

          <script type="text/x-jsrender" id="j-specCard">
              {{if count == 1 tmpl="#j-firstTpl" /}}
          </script>
          <script type="text/x-jsrender" id="j-firstTpl">
              <h3>this is first template</h3>
          </script>

          當然如果你的情況比較復雜,那么你可以混著用

          <script type="text/x-jsrender" id="j-specCard">
              {{if count == 1 tmpl="#j-firstTpl" }}
              {{else count == 2 tmpl="#j-secondTpl"}}
              {{else}}
              <p>no template</p>
              {{/if}}
          </script>
          <script type="text/x-jsrender" id="j-firstTpl">
              <h3>this is first template</h3>
          </script>
          <script type="text/x-jsrender" id="j-secondTpl">
              <h3>this is second template</h3>
          </script>

          有了引用模板的功能,我們就完全可以把比較通用的代碼提取出來寫一個模板,減少代碼的冗余。


          6. 使用{{for}}循環對數據進行循環或對對象進行遍歷

          jsrender的for循環會默認把數組或對象的第一層循環遍歷掉,我們只要管里面的數據就行了,而且使用了循環之后的模板也可以單獨寫成一個模板,在for循環中引用,循環數組的時候可以使用{{:#index}}來獲取當前數組的下標,并且index是從0開始。
          傳入模板的數據結構

          <script>
          (function(jq, g) {
          
              var animal = {
                  'kind': 4,
                  'price':{
                      'cow': 19999,
                      'pig': 1888
                  },
                  'list': [
                      {
                          'name': 'cow',
                          'count': 4,
                          'foot': 4
                      },
                      {
                          'name': 'chicken',
                          'count': 5,
                          'foot': 2
                      }
                  ]
              },
                  //獲取模板
                  jsRenderTpl = $.templates('#j-specCard'),
                  //末班與數據結合
                  finalTpl = jsRenderTpl(animal);
          
              $('.box').html(finalTpl);
          
          })(jQuery, window)
          </script>
          <script type="text/x-jsrender" id="j-specCard">
              {{!-- animal 對象已經被默認遍歷,所以屬性前不用加animal.就可訪問到 --}}
              <h3>there have {{:kind}} kinds animal</h3>
              <p>and the cow price is {{:price.cow}}</p>
              <p>and the cow price is {{:price.pig}}</p>
          
              {{!--
              也可以這樣對對象進行for循環
              {{for price}}
              <p>and the cow price is {{:cow}}</p>
              <p>and the cow price is {{:pig}}</p>
              {{/for}}
              --}}
              <ul>
                  {{!-- 對對象數組進行循環 --}}
          
                  {{for list}}
                  <li>{{:#index + 1}}. this animal call {{:name}}, and has {{:count}}, it has {{:foot}} foots</li>
                  {{/for}}
          
                  {{!--
                      也可以使用模板引入作為循環的模板
                      {{for list tmpl="#j-listTpl" /}}
                   --}}
          
              </ul>
          
          </script>
          <script type="text/x-jsrender" id="j-listTpl">
              <li>this animal call {{:name}}, and has {{:count}}, it has {{:foot}} foots</li>
          </script>

          當循環數組或者遍歷對象的時候,如果在{{for}}{{/for}}中間加上{{else}},還可以對遍歷的對象進行判斷,如果該對象或者屬性不存在,那么就顯示其他的內容。

          {{!-- 遍歷的時候順便判斷merbers是否存在 --}}
          {{for members}}
              <div>{{:name}}</div>
          {{else}} 
              <div>No members!</div>
          {{/for}}


          7. 使用{{props}}遍歷對象并且獲取到對象的key/value

          當我們遍歷對象需要使用到對象的key值時,使用props可以獲取到key/value值,而且也可以在for循環中進行對象的遍歷,在數據循環中獲取可以使用#data獲取到當前的對象,當然也可以使用引入外部模板來當做循環模板。
          傳入模板的數據結構

          <script>
          (function(jq, g) {
          
              var animal = {
                  'kind': 4,
                  'price':{
                      'cow': 19999,
                      'pig': 1888
                  },
                  'list': [
                      {
                          'name': 'cow',
                          'count': 4,
                          'foot': 4
                      },
                      {
                          'name': 'chicken',
                          'count': 5,
                          'foot': 2
                      }
                  ]
              },
                  //獲取模板
                  jsRenderTpl = $.templates('#j-specCard'),
                  //末班與數據結合
                  finalTpl = jsRenderTpl(animal);
          
              $('.box').html(finalTpl);
          
          })(jQuery, window)
          </script>

          模板

          <script type="text/x-jsrender" id="j-specCard">
              {{!-- 簡單的對象遍歷 --}}
              {{props price}}
              <p>and the {{:key}} price is {{:prop}}</p>
              {{/props}}
          
              <ul>
                  {{!-- 在數據循環中再進行對象的遍歷,病獲取到key/prop --}}
          
                  {{for list}}
                  <li>{{:#index + 1}}. 
                      {{props #data}}
                          <b>{{:key}}</b> is {{>prop}}  
                      {{/props}}
                  </li>
                  {{/for}}
          
                  {{!--
                      也可以使用模板引入作為循環的模板
                      {{for list tmpl="#j-listTpl" /}}
                   --}}
          
              </ul>
          
          </script>
          <script type="text/x-jsrender" id="j-listTpl">
              <li>{{:#index + 1}}. 
                  {{props #data}}
                      <b>{{:key}}</b> is {{>prop}}  
                  {{/props}}
              </li>
          </script>

          當然,在prop也可以在遍歷對象的時候對對象進行判斷,只要在prop變遷中加入{{else}},如果對象為undefined或對象為空,那么就執行else邏輯。

          {{props address}}
              <b>{{>key}}:</b>{{>prop}} <br />
          {{else}} 
              The address is blank (no properties)!
          {{/props}}


          8. 使用{{include}}引入外部模板或者改變模板的上下文

          雖然我們可以在{{for}}循環中或者{{if}}標簽中直接引入模板,但是{{include}}引入模板才是符合我們的認知,應該什么標簽該干什么事來的。

          <script type="text/x-jsrender" id="j-specCard">
              {{if case == 1}}
                  {{include tmpl="#j-case1Tpl" /}}
              {{else case == 2}}
                  {{include tmpl="#j-case2Tpl" /}}
              {{else}}
                  <p>no data</p>
              {{/if}}
          
          </script>
          <script type="text/x-jsrender" id="j-case1Tpl">
              <h3>{{:data.title}}</h3>
              <p>{{:data.text}}</p>
          </script>
          <script type="text/x-jsrender" id="j-case2Tpl">
              <h3>{{:data.title}}</h3>
              <p>{{:data.text}}</p>
          </script>

          模板數據

              var condition = {
                  'case': 1,
                  'data': {
                      'title': 'this is first case',
                      'text': 'case one text'
                  }
              },
                  //獲取模板
                  jsRenderTpl = $.templates('#j-specCard'),
                  //末班與數據結合
                  finalTpl = jsRenderTpl(condition);
          
              $('.box').html(finalTpl);

          使用{{include}}標簽引入模板顯得比較語義化,雖然并沒有什么差別。除了引入模板,{{include}}還可以在引入模板的同時引入對象或者數組,來改變所引入模板的上下文

          <script type="text/x-jsrender" id="j-specCard">
              {{if case == 1}}
                  {{include tmpl="#j-case1Tpl" /}}
              {{else case == 2}}
                  {{include data tmpl="#j-case1Tpl" /}}
              {{else}}
              {{else case == 3}}
                  {{include data1 tmpl="#j-case2Tpl" /}}
              {{else}}
                  <p>no data</p>
              {{/if}}
          
          </script>
          <script type="text/x-jsrender" id="j-case1Tpl">
              {{!-- for循環會默認取到傳進來的對象 使用data.title是訪問不到的 --}}
              {{!-- 傳進來的對象必須手動循環 --}}
              {{for}}
                  <h3>{{:title}}</h3>
                  <p>{{:text}}</p>
              {{/for}}
              {{!--
                  或者這樣使用
                  <h3>{{:#data.title}}</h3>
                  <p>{{:#data.text}}</p>
              --}}
          </script>
          <script type="text/x-jsrender" id="j-case2Tpl">
              {{!-- :length 可以獲取當前數組的長度 --}}
              {{:length}}
              {{!-- 傳進來的數組必須手動循環 --}}
              {{for #data}}
                  <h3>{{:title}}</h3>
                  <p>{{:text}}</p>
              {{/for}}
              {{!-- 
                  <h3>{{*:extraData.title}}</h3>
                  <p>{{*:extraData.text}}</p>
              --}}
          </script>

          傳入的模板數據

              var condition = {
                  'case': 2,
                  'data': {
                      'title': 'this is first case',
                      'text': 'case one text'
                  },
                  'data1': [
                      {
                          'title': 'i am outer fisrt title',
                          'text': 'it is me,diffrent light'
                      },
                      {
                          'title': 'i am outer second title',
                          'text': 'it is me,diffrent light'
                      }
                  ]
              };

          而引入外部全局對象或者數組,發現循環 /遍歷不了,過后再研究


          9、使用{{converters:value}}把value轉換成所需要的格式

          當后端給我們返回的數據格式跟頁面所以展示的格式不一樣的時候,我們就需要對數據進行轉換。比如說后端返回時間的毫秒數,可是頁面卻要顯示 年-月-日的格式或者是后端返回小寫的字符,頁面卻要顯示成大寫的字符,這個時候轉換器就派上用場了。
          jsrender提供了api $.views.converters()來注冊轉換方法。

              <script type="text/x-jsrender" id="j-myPersonalInfoTpl">
                  <div>
                      <h3>{{upper:name}}</h3>
                      <p>{{:age}}</p>
                  </div>
              </script>
          
              $.views.converters({
                  upper: function(val){
                      return val.toUpperCase();
                  }
              })
          
              //使用jQuery選擇器獲取script標簽聲明的jsrender模板并傳入數據跟一些方法渲染模板
              var myPersonalTpl = $("#j-myPersonalInfoTpl").render(info);


          10、使用{{:~helper(value)}}對傳入的參數value做處理

          當我們拿到的數據不符合展示的需求是,我們需要對數據進行處理,那么我們可以使用輔助函數,把原始當參數傳入,返回我們需要的數據。
          jsrender提供了$.views.helper()方法來注冊輔助函數。并使用~當前綴來調用輔助函數。

          <script type="text/x-jsrender" id="j-myPersonalInfoTpl">
                  <div>
                      <h3>{{:~hello(firstName, lastName)}}</h3>
                      <p>{{:age}}</p>
                  </div>
          </script>
          
              var info = {
                  firstName: 'alice',
                  lastName: 'Jogh',
                  age: 18
              };
          
              $.views.helpers({
                  hello: function(fisrtName, lastName){
                      return 'Hello ' + fisrtName + ' ' + lastName;
                  }
              })
          
              //使用jQuery選擇器獲取script標簽聲明的jsrender模板并傳入數據渲染模板
              var myPersonalTpl = $("#j-myPersonalInfoTpl").render(info);


          二、常用API


          1. $.templates()

          $.templates()方法是用來注冊或者編譯模板的,使用的情況有以下幾種。

          • 把html字符串編譯編譯成模板。
          • 獲取使用script標簽聲明的模板,并返回一個模板對象
          • 把html字符串或者在script標簽中聲明的模板注冊成命名模板
          • 獲取之前就存在的命名模板
          • 在nodejs中,根據文件路徑獲取一個模板對象

          我們正常使用的方式就是使用$.templates()方法把html字符串編譯成模板,返回一個模板對象,然后調用該對象的render方法并傳入數據,就可以得到一份完整的html字符串代碼。比如:

          var info = {
                  name: 'alice',
                  age: 18
              };
          
              //獲取模板
              var jsRenderTpl = $.templates('<div><h3>{{:name}}</h3><p>{{:age}}</p></div');
              //模板與數據結合
              var finalTpl = jsRenderTpl.render(info);
              //也可以這樣用 jsRenderTpl(info);

          或者我們也可以給模板定義一個名稱

              //定義一個命名模板
              $.templates('myPersonalInfoTpl', '<div><h3>{{:name}}</h3><p>{{:age}}</p></div');
              //模板與數據結合
              var finalTpl = $.render.myPersonalInfoTpl(info);

          當然,我們也可以把html字符串單獨寫在script標簽中,然后根據id來獲取

          <script type="text/x-jsrender" id="j-myPersonalInfoTpl">
              <div>
                  <h3>{{:name}}</h3>
                  <p>{{:age}}</p>
              </div>
          </script>
          </body>
          <script src="../lib/jquery-1.11.2.min.js"></script>
          <script src="../lib/jsrender.js"></script>
          <script>
          (function(jq, g) {
              //定義一個命名模板
              $.templates('myPersonalInfoTpl', '#j-myPersonalInfoTpl');
              //模板與數據結合
              var finalTpl = $.render.myPersonalInfoTpl(info);
              $('.box').html(finalTpl);
          
          })(jQuery, window)
          </script>

          更想當然,還可以在一個templates()方法里面注冊多個命名模板

          //定義一個命名模板
              $.templates({
                  'myPersonalInfoTpl': '#j-myPersonalInfoTpl',
                  'externalTpl': '<p>this is externalTpl</p>'
              });
              //模板與數據結合
              var finalTpl = $.render.myPersonalInfoTpl(info);
              var externalTpl = $.render.externalTpl();
          
              $('.box').html(finalTpl).append(externalTpl);

          還可以指定一些只供這個模板使用的一些方法

              <script type="text/x-jsrender" id="j-myPersonalInfoTpl">
                  <div>
                      <h3>{{upper:~append(name, ' stev')}}</h3>
                      <p>{{:age}}</p>
                  </div>
              </script>
          
              //定義一個命名模板,并指定只供這個模板使用的轉換方法與輔助方法
              $.templates("myPersonalInfoTpl", {
                  markup: "#j-myPersonalInfoTpl",
                  converters: {
                      upper: function(val) {
                          return val.toUpperCase();
                      }
                  },
                  helpers: {
                      append: function(a, b) {
                          return a + b;
                      }
                  }
              });
              //模板與數據結合
              var finalTpl = $.render.myPersonalInfoTpl(info);


          2、渲染模板的render()方法

          當我們使用$.templates()方法注冊一個模板對象時,最后還是需要把模板對象跟數據結合得到最終的html字符串的,render()的使用方式有以下三種

          1. 當模板對象myPersonalTpl是使用$.templates()注冊的模板時,只能使用myPersonalTpl.render(data)的方式來渲染模板
             //定義一個匿名模板
             var myPersonalTpl = $.templates("#j-myPersonalInfoTpl");
             //模板與數據結合
             var finalTpl = myPersonalTpl(info);
          2. 當模板對象myPersonalTpl是以命名模板的方式注冊時,需要使用$.render.myPersonalTpl(data)或者$.render['myPersonalTpl'](data)的方式來渲染模板
            //定義一個命名模板
            $.templates("myPersonalInfoTpl","#j-myPersonalInfoTpl");
            //模板與數據結合
            var finalTpl = $.render.myPersonalInfoTpl(info);
          3. 當使用jQuery、并且模板是在script標簽中聲明時,還可以直接使用$("#personTemplate").render(data),并不需要調用$.templates()方法來注冊模板。

            var myHelpers = {
                 upper: function(val){
                     return val.toUpperCase();
                 }
             }
             //使用jQuery選擇器獲取script標簽聲明的jsrender模板并傳入數據跟一些方法渲染模板
             var myPersonalTpl = $("#j-myPersonalInfoTpl").render(info, myHelpers);
            
             $('.box').html(finalTpl);

          我們還可以在渲染模板的同時,傳入一些函數供模板使用

          $.render.myTmpl(data, helpersOrContext)


          3、 使用$.views.helpers()方法注冊輔助函數

          當我們拿到的數據跟頁面顯示的數據有差別、或者是我們需要把原數據轉化成其他格式的數據時,我們使用使用一些輔助函數來實現,jsrender提供了兩種方式,一種是helper函數,一種是converters轉換器。我們先講輔助函數helper。helper方法是以 "~" 為前綴作為方法的標示,在加上方法名,然后把值當參數傳進去

          //example
          {{:~myHelperValue}}
          {{:~myHelperFunction(name, title)}}
          {{for ~myHelperObject.mySortFunction(people, "increasing")}} ... {{/for}}

          輔助函數helper注冊方式有以下三種:

          • 使用$.views.helpers()注冊全局的helper方法。
            當我們需要一些比較通用的方法時,可以提取出來寫到公用的js文件中去,以后就不用重新寫一遍了。

              <div id="box"></div>
              <script id="myPersonInfo" type="text/x-jsrender">
                  <h3>my name is {{:~concat(firstName, lastName)}}</h3>
                  <p>{{:~util.addPrefix(age)}}</p>
              </script>
              <script>
                  var info = {
                      firstName: 'bolin',
                      lastName: 'liao',
                      age: 18
                  };
            
                  // 定義全局的helper方法
                  $.views.helpers({
                      concat: function(first , last){
                          return first + '  ' + last;
                      },
                      util: {
                          prefix: 'age is  ',
                          addPrefix: function(age){
                              return this.prefix + age;
                          }
                      }
                  });
            
                  var html = $('#myPersonInfo').render(info);
                  $('#box').html(html);
              </script>
          • 寫局部的輔助方法
            當我們的某一個頁面有多處使用一個輔助方法,但是又不夠通用,不必寫到common文件去時,我們可以寫只供這個頁面使用的輔助方法。

                  // 定義局部的helper方法
                  var myHelper = {
                      concat: function(first , last){
                          return first + '  ' + last;
                      },
                      util: {
                          prefix: 'age is  ',
                          addPrefix: function(age){
                              return this.prefix + age;
                          }
                      }
                  }
            
                  //并在渲染模板的時候把myHelper當做參數傳進去
                  var html = $('#myPersonInfo').render(info, myHelper);
          • 只給特定的模板寫輔助函數,其實也就是在定義模板的時候把helper傳進去

                  //注冊一個命名模板,并指定helper方法
                  $.templates({
                      myPersonInfo: {
                          markup: '#myPersonInfo',
                          helpers: {
                              concat: function(first , last){
                                  return first + '  ' + last;
                              },
                              util: {
                                  prefix: 'age is  ',
                                  addPrefix: function(age){
                                      return this.prefix + age;
                                  }
                              }
                          }
                      }
                  });
            
                  //渲染模板,命名模板只能使用$.render調用
                  var html = $.render.myPersonInfo(info);
                  $('#box').html(html);


          4、使用$.views.converters()注冊轉換器

          在jsrender中,轉換器主要是方便對數據或表達式的的結果進行處理或者格式化,jsrender本身自帶了三個轉換器,比如:

          {{html:'<b>bolin</b>'}} //- 對html標簽進行編碼,原樣輸出 :<b>bolin</b>
          {{>'<b>bolin</b>'}} //同上,html的別名
          {{url:"<_>_\"_'"}} // 對特殊字符進行編碼 基本是 <,>,",'...    :%3C_%3E_%22_'
          {{attr:value}} //對標簽的屬性值進行編碼,也是字符的轉換
          & → &< → <> → >\x00 → ?' → '" → "` → `= → =

          當然,僅僅是這三個轉換時不夠用的,jsrender提供了自定義轉換器的方法。$.views.converters()。比如我想要定義一個時間格式化的轉換器跟大小寫轉換的轉換器。

              <script id="myPersonInfo" type="text/x-jsrender">
                  <h3>{{upper: 'my name is ' + name}}</h3>
                  <p>now is {{dateFormat: time}}</p>
              </script>
              <script>
                  var info = {
                      name: 'bolin liao',
                      time: new Date()
                  };
          
                  //注冊全局轉化器
                  $.views.converters({
                      dateFormat: function(val){
          
                          var time = new Date();
          
                          time.setTime(val || 0); //設置需要格式化的時間
                          return (time.getMonth() + 1) + '月' + time.getDate() + '日';
                      },
                      upper: function(val){
                          console.log(val);
                          return val.toUpperCase();
                      }
                  });
          
                  //渲染模板,命名模板只能使用$.render調用
                  var html = $('#myPersonInfo').render(info);
                  $('#box').html(html);
              </script>

          你會發現,其實轉換器跟輔助函數差不多嘛,只是使用的方法不一樣而已。雖然實現都差不多,但還是有點區別的,轉換器也分全局定義跟局部定義,局部定義的轉換只要把模板當做參數傳進去就好了,所定義的轉換器只能在此模板中生效。

              <script id="myPersonInfo" type="text/x-jsrender">
                  <h3>{{upper: 'my name is ' + name}}</h3>
                  <p>now is {{dateFormat: time}}</p>
              </script>
               //myText中的轉換器不起作用,并報錯
              <script id="myText" type="text/x-jsrender">
                  <h3>{{upper: title}}</h3>
                  <p>now is {{dateFormat: time}}</p>
              </script>
          
              //注冊局部轉換器,指定myPersonInfo模板可用
              $.views.converters({
                  dateFormat: function(val){
          
                      var time = new Date();
          
                      time.setTime(val || 0); //設置需要格式化的時間
                      return (time.getMonth() + 1) + '月' + time.getDate() + '日';
                  },
                  upper: function(val){
                      console.log(val);
                      return val.toUpperCase();
                  }
              }, $.templates('#myPersonInfo'));
          
              //渲染模板,命名模板只能使用$.render調用
              var html = $('#myPersonInfo').render(info);
              $('#box').html(html);
          
              //不可用
              var html = $('#myText').render(text);
              $('#box').append(html);

          除了使用在{{convert:}}標簽中之外,還可以在{{if}},{{for}}標簽中使用,可以說是在任何標簽中使用,語法如下:

          {{someTag ... convert=...}}
          //if語句
          {{if convert='inList' item itemList}}...{{/if}}
          //for語句
          {{for people convert='even'}}

          在其他標簽中使用時,只是需要把轉化器賦值給convert,當然也可以把輔助方法賦值給convert,比如

          {{:name convert=~hlp.bold}}

          但是呢,如果你使用{{>name convert=~hlp.bold}}的話,是會報錯的,還是老老實實使用輔助方法的形式,除了以上的使用方式之外,convert還提供了一些比較好的功能,比如使用this.tagCxt.props可以獲取到標簽中定義的屬性,使用this.tagCxt.view.data可以獲取到標簽中所有的變量。

              <script id="myPersonInfo" type="text/x-jsrender">
                  <h3>{{concat: first last age desc="123" myAttr="test"}}</h3>
              </script>
          
              //注冊局部轉換器,指定myPersonInfo模板可用
              $.views.converters({
                  concat: function(){
          
                      console.log(this.tagCtx.props);//Object {desc: "123", myAttr: "test"}
          
                      console.log(this.tagCtx.view.data);//Object {first: "bolin", last: " liao", age: 18}
          
                  }
              });


          5、使用$.views.tags()注冊自定義標簽

          jsrender 提供了一些內置的標簽,但往往是不夠用的,所以提供了$.views.tags()方法來定義一些比較靈活的標簽。自定義標簽比較靈活,能控制、訪問的元素也比較多,比如寫在該標簽里面的args、props、甚至整個view model對象里面的全部數據。使用$.views.tags注冊自定義標簽的語法有以下四種

          1. $.views.tags('myTag', tagOptions); 當自定義的標簽需要要模板與方法時,一般會使用這種方式來注冊自定義標簽,我們可以在render方法里面處理參數或者屬性,然后渲染模板,this.tagCxt對象下,有當前view model的數據供訪問

          Paste_Image.png
              <script id="myPersonInfo" type="text/x-jsrender">
                  {{myPersonInfo name age addPrefix=false /}}
              </script>
          
              var info = {
                  name: 'bolin',
                  age: 20
              };
          
              $.views.tags({
                  'myPersonInfo': {
                      render: function(){
                          //這里可以獲取到自定義標簽里面的屬性或者參數
                          //可以使用 this.tagCtx.args, this.tagCtx.props, this.tagCtx.view.data 訪問 view model里面的任何數據
          
                          console.log(this.tagCtx);
                          if (this.tagCtx.props.addPrefix) {
          
                              return '<h3>Hello, ' + this.tagCtx.args[0] + '</h3><p>' + this.tagCtx.args[1] + '</p>';
                          }else{
          
                              //使用this.tagCtx.render({name:'lbl'})來渲染定義的模板,并把模板需要的數據傳進去
                              return this.tagCtx.render({name:'lbl'}) + '<h3>' + this.tagCtx.args[0]  +'</h3><p>' + this.tagCtx.args[1] + '</p>';
                          }
                      },
                      template: '<h2>{{:name}}</h2>'
                  }
              });

          當然,如果我們不需要模板,那么就只定義一個方法就好了。

              $.views.tags('myPersonInfo', function(){
          
                  if (this.tagCtx.props.addPrefix) {
          
                      return '<h3>Hello, ' + this.tagCtx.args[0] + '</h3><p>' + this.tagCtx.args[1] + '</p>';
                  }
              });

          當然,也可能你的自定義標簽只需要模板,并不需要方法來處理,那么也是沒問題的,當然模板里面也是可以訪問各種參數、屬性的,只是需要使用~tag.tagCtx對象訪問。

              <script id="myPersonInfo" type="text/x-jsrender">
                  {{myPersonInfo name age=age /}}
              </script>
          
              $.views.tags('myPersonInfo', {
                  template: '<h3>{{:~tag.tagCtx.args[0]}}</h3><p>{{:~tag.tagCtx.props.age}}</p>'
              });
          
              //也可以這樣
              <script id="myPersonInfo" type="text/x-jsrender">
                  {{myPersonInfo name age addPrefix=false}}
                      <h3>{{:~tag.tagCtx.args[0]}}</h3>
                      <p>no info</p>
                  {{/myPersonInfo}}
              </script>
          
              //也可以使用tag.tagCtx.content獲取到自定義標簽中的內容
              $.views.tags('myPersonInfo', {
                  template: '{{if ~tag.tagCtx.props.addPrefix == true}}\
                              <h3>Hello, {{:~tag.tagCtx.args[0]}}</h3>\
                              <p>{{:~tag.tagCtx.props.age}}</p>\
                              {{else tmpl=~tag.tagCtx.content}}\
                              {{:~tag.tagCtx.content}}\
                              {{/if}}'
              });
          
            //或者這樣
              <script id="teamTemplate" type="text/x-jsrender">
                <p><b>{{:title}}</b></p>
                <ul>
                  {{range members start=1 end=2}} 
                    <li>
                      {{:name}}
                    </li>
                  {{/range}}
                </ul> 
              </script>
          
              $.views.tags("range", {
                  template: 
                      "{{for ~tag.tagCtx.args[0]}}" +
                      "{{if #index >= ~tag.tagCtx.props.start && #index <= ~tag.tagCtx.props.end}}" +
                      "{{include tmpl=~tag.tagCtx.content/}}" +
                      "{{/if}}" +
                      "{{/for}}"
              });

          當然也可以為某個模板注冊私有的自定義標簽

              $.views.tags({
                myTag1: ...,
                myTag2: ...
              }, parentTemplate);


          6、使用$.views.settings.debugMode()開啟調試模式

          當我們使用jsrender寫代碼時,難免會報一些錯,然后直接在控制臺拋出錯誤異常。但是我們想對錯誤信息做一些處理,比如直接把異常輸出到頁面,或者自定義錯誤信息為字符竄,或者拋出錯誤的時候,先調用函數處理再拋出錯誤。jsrender提供了$.views.settings.debugMode()傳入不同的參數來改變全局拋出異常的情況。

          1. false 內容不會被渲染并且在控制臺拋出異常 (默認)
          2. true 拋出的異常會渲染在頁面中,在控制臺中沒有異常拋出
          3. "string" 字符串會替代錯誤信息渲染在頁面中,在控制臺沒有異常拋出
          4. function 在異常拋出之前,會先經過傳入的方法處理,如果此方法沒有return,那么就會把錯誤信息渲染到頁面中,如果有return,那么頁面中就會渲染return 的信息
              $.views.settings.debugMode(function(err){
          
                  var errMsg = '';
          
                  if(err){
          
                      errMsg = 'here has error the err is ' + err;
                  }
                  return errMsg;
              });

          當然,除了為全局處理錯誤信息之外,也可以使用onError屬性為某一個標簽定義錯誤信息,如果你已經在全局設置了處理錯誤信息的方法,并且傳入的參數有返回值(上面提到的3跟4),onError屬性是不會起作用的

              {{:address.street onError="Address unavailable"}}
              {{for phones() onError="<em>No phones</em>"}}
              {{:address.street onError=name + " has no address"}}
              {{:address.street onError=~errorMessages(1, name, 'address')}}
              {{myCustomTag ... onError=""}}
          
              $.views.settings.debugMode("this is global err"); //會覆蓋上面的onError屬性
              or
              $.views.settings.debugMode(function(err){
          
                  var errMsg = '';
          
                  if(err){
          
                      errMsg = 'here has error the err is ' + err;
                  }
                  return errMsg; //如果return 就會渲染這個,如果不return 就會渲染onError屬性的值
              });

          當我們使用render()方法渲染模板的時候,我們想查看某個對象或者某個屬性的值,但是并不能在模板中打斷點,jsrender提供以下方式在渲染模板的過程中輸出對象或者屬性的值

          {{dbg expression/}}  tag
          {{dbg: expression}}   convert
          {{:~dbg(expression)}}  helper

          以上的三種方式都會把值渲染在頁面,并在控制臺中輸出值,但是呢,如果值是一個對象,那么就會輸出字符串,比如

          JsRender dbg breakpoint: [object Object]

          我們需要看對象里面有什么屬性,但是卻給我們輸出的是字符串,顯然不方便調試,所以我們可以重寫這個調試標簽,讓輸入值原樣輸出

              //重寫dbg調試模式
              $.views.helpers({
                  dbg: function(val){
          
                      try {
                          console.log(val);
                          return val;
                      }catch (e) {
                          console.log(e);
                      }
                  }
              });
          
              $.views.converters({
                  dbg: function(val){
          
                      try {
                          console.log(val);
                          return val;
                      }catch (e) {
                          console.log(e);
                      }
                  }
              });
          
              $.views.tags('dbg', function(val){
          
                  try {
                      console.log(val);
                      return val;
                  }catch (e) {
                      console.log(e);
                  }
              });

          這樣重寫之后,控制臺輸出變成這樣,就比較方便調試了

          Object {name: "bolin", age: 20}

          作者:木白no1  來源:簡書  
          鏈接:http://www.jianshu.com/p/3151d2256410


          站長推薦

          1.阿里云: 本站目前使用的是阿里云主機,安全/可靠/穩定。點擊領取2000元代金券、了解最新阿里云產品的各種優惠活動點擊進入

          2.騰訊云: 提供云服務器、云數據庫、云存儲、視頻與CDN、域名等服務。騰訊云各類產品的最新活動,優惠券領取點擊進入

          3.廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入

          鏈接: http://www.modern-decoration.com.cn/article/detial/109

          CSS重置默認樣式reset.css代碼模板

          由于各大瀏覽器存在兼容性問題,同一個CSS屬性在不同瀏覽器下的表現不一定相同,有經驗的前端設計者都會自定義一個重置瀏覽器樣式的CSS文件,在這個文件中定義一些針對不同的瀏覽器最終表現出一致的代碼

          PHP框架中JS優雅獲取模板變量的方式

          在使用PHP框架(本文以ThinkPHP為例)進行頁面開發的時候,經常遇到需要將控制器方法中的模板變量代入到頁面JS內操作的情況,常見的方式如:

          Vue模板語法

          Vue.js 使用了基于 HTML 的模板語法,允許開發者聲明式地將 DOM 綁定至底層 Vue 實例的數據。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循規范的瀏覽器和 HTML 解析器解析。

          我來聊聊面向模板的前端開發

          在軟件開發中,研發效率永遠是開發人員不斷追求的主題之一。于公司而言,在競爭激烈的互聯網行業中,產出得快和慢也許就決定著公司的生死存亡;于個人而言,效率高了就可以少加班,多出時間去提升自己、發展愛好、陪伴家人,工作、生活兩不誤

          面向模板的前端開發

          在軟件開發中,研發效率永遠是開發人員不斷追求的主題之一。于公司而言,在競爭激烈的互聯網行業中,產出得快和慢也許就決定著公司的生死存亡;于個人而言,效率高了就可以少加班,多出時間去提升自己

          如何選擇 Web 前端模板引擎?

          模板引擎負責組裝數據,以另外一種形式或外觀展現數據。瀏覽器中的頁面是 Web 模板引擎最終的展現。無論你是否直接使用模板引擎,Web 模板一直都在,不在前端就在后端,它的出現甚至可以追溯到超文本標記語言 HTML 標準正式確立之前。

          Vue模板語法、事件和表單使用

          文本綁定,兩個大括號,中間加上data里面的數據,message里面不僅可以是變量還可以是表達式;JS表達式(計算、拼接、只能是單個表達式)插入HTML代碼(慎用!防止XSS攻擊 ),我們可以直接在data里面定義html代碼

          Bootstrap后臺管理模板有哪些?

          在開發項目中,后臺管理因為面向群體相對比較固定,使用Bootstrap后臺模板可以讓后端開發很輕松的就展現給客戶一個響應式的后臺,節約前端開發的時間。下面給大家分享一下最值得擁有的免費Bootstrap后臺管理模板

          Vue模板語法中數據綁定

          們通過 vue 對象修改數據可以直接影響到 DOM 元素,但是,如果直接修改 DOM 元素,卻不會影響到 vue 對象的數據;我們把這種現象稱為 單向數據綁定 ;通過 v-model 指令展示表單數據,此時就完成了 雙向數據綁定

          artTemplate模板引擎的使用

          artTemplate是騰訊開源的前端模板框架,和mustache,handlerbars類似,在web項目中可以很方便的使用,上手快,如果用過mustache,那么幾乎可以快速切換到template框架上來。

          內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權或違規,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全運營推廣

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网