AngularJS 示例:模板控制語句 for

2018-07-26 17:22 更新

這個(gè)示例嘗試實(shí)現(xiàn)一個(gè)重復(fù)語句,功能同官方的 ngRepeat ,但是使用方式類似于我們通常編程語言中的 for 語句:

<div ng-controller="TestCtrl" ng-init="obj_list=[1,2,3,4]; name='name'">
  <ul>
    <for o in obj_list>
      <li>{{ o }}, {{ name }}</li>
    </for>
  </ul>
  <button ng-click="obj_list=[1,2]; name='o?'">修改</button>
</div>

同樣,我們從上面的使用方式去考慮這個(gè)指令的實(shí)現(xiàn):

  • 這是一個(gè)完全的控制指令,所以單個(gè)節(jié)點(diǎn)應(yīng)該只有它一個(gè)指令起作用就好了,于是權(quán)重要比較高,并且“到此為止”—— priority 設(shè)置為 1000 , terminal 設(shè)置為 true 。
  • 使用時(shí)的語法問題。事實(shí)上瀏覽器會(huì)把 for 節(jié)點(diǎn)補(bǔ)充成一個(gè)正確的 HTML 結(jié)構(gòu),即里面的屬性都會(huì)變成類似 o="" 這樣。我們通過節(jié)點(diǎn)的 outerHTML 屬性取到字符串并解析取得需要的信息。
  • 我們把 for 節(jié)點(diǎn)之間的內(nèi)容作為一個(gè)模板,并且通過循環(huán)多次渲染該模板之后把結(jié)果填充到合適的位置。
  • 在處理上面的那個(gè)模板時(shí),需要不斷地創(chuàng)建新 scope 的,并且 o 這個(gè)成員需要單獨(dú)賦值。

注意:這里只是簡單實(shí)現(xiàn)功能。官方的那個(gè) ngRepeat 比較復(fù)雜,是做了專門的算法優(yōu)化的。當(dāng)然,這里的實(shí)現(xiàn)也可以是簡單把 DOM 結(jié)構(gòu)變成使用 ngRepeat 的形式 :)

JS 部分代碼:

var app = angular.module('Demo', [], angular.noop);

app.directive('for', function($compile){
  var compile = function($element, $attrs, $link){
    var match = $element[0].outerHTML.match('<for (.*?)=.*? in=.*? (.*?)=.*?>');
    if(!match || match.length != 3){throw Error('syntax: <for o in obj_list>')}
    var iter = match[1];
    var list = match[2];
    var tpl = $compile($.trim($element.html()));
    $element.empty();

    var link = function($scope, $ielement, $iattrs, $controller){

      var new_node = [];

      $scope.$watch(list, function(list){
        angular.forEach(new_node, function(n){n.remove()});
        var scp, inode;
        for(var i = 0, ii = list.length; i < ii; i++){
          scp = $scope.$new();
          scp[iter] = list[i];
          inode = tpl(scp, angular.noop);
          $ielement.before(inode);
          new_node.push(inode);
        }

      });
    }

    return link;
  }
  return {compile: compile,
          priority: 1000,
          terminal: true,
          restrict: 'E'};
});

app.controller('TestCtrl', angular.noop);
angular.bootstrap(document, ['Demo']);
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)