簡體   English   中英

根據子元素應用CSS類

[英]Applying css class depending on subelements

我想根據子元素是否符合特定條件將css類設置為列表項。 結構類似於以下示例:

<ul ng-controller="Navigation">
    <li><a href="#">Category A</a>
        <ul>
            <li><a href="a1.html">a1</a></li>
            <li><a href="a2.html">a2</a></li>
        </ul>
    </li>
    <li><a href="#">Category B</a>
        <ul>
            <li><a href="b1.html">b1</a></li>
            <li><a href="b2.html">b2</a></li>
        </ul>
    </li>
    <li><a href="contact.html">contact</a></li>
</ul>

我的模型是當前頁面,例如a2.html 如果鏈接具有與模型值相同的href屬性,則它應具有某個css類( active )。 這可以用以下表達式完成:

<a href="a1.html" ng-class="{'active': currentPage == 'a1.html'}>

但這有點不a1.html ,因為我必須重復文件名( a1.html )。 是否可以將當前元素傳遞給函數? 像這樣: ng-class="getClass(currentElement)"

下一個問題是,我想根據子級是否active該類來選擇父級元素。 如果在我上面的示例中選擇了<a href="a1.html">a1</a> ,則Category A應使該類active

結論

'stewie的解決方案有效,但是我得出的結論是Angular並不是完成這項工作的最佳工具。 它不是Web“應用程序”(Angular的域),而是靜態html,應該對其進行豐富。

這個簡單的jQuery代碼段可以完成這項工作:

var activeLink = $("a").filter(function() {
  return $(this).attr("href") == currentPage();
});
activeLink.addClass("active");
activeLink.parents("li").children("a").addClass("active");

可以通過在UL元素上使用自定義指令來完成此操作,該指令將在模型更改時遍歷列表,並在匹配項上設置適當的“活動”類。 請以此柱塞為例 請注意,該指令可以進一步優化。 這只是一個示范。

HTML:

<ul menu ng-controller="Navigation">
  <li><a href="#">Category A</a>
    <ul>
      <li><a href="a1.html">a1</a></li>
      <li><a href="a2.html">a2</a></li>
    </ul>
  </li>
  <li><a href="#">Category B</a>
    <ul>
      <li><a href="b1.html">b1</a></li>
      <li><a href="b2.html">b2</a></li>
    </ul>
  </li>
  <li><a href="contact.html">contact</a></li>
</ul>

JS:

var app = angular.module('plunker', []);
app.controller('Navigation', 
    function($scope) {}
  );

app.directive('menu',
  function(){
    return {
      link: function ($scope, $element) {
        var link, li;
        $scope.$watch('currentPage', function(page){
          activate(page);
        });

        function activate(page){
          angular.forEach($element.find('li'), function(elm){
            li = angular.element(elm);
            link = li.find('a');
            if(link.attr('href') === $scope.currentPage){
              li.addClass('active');
              li.parents('li').addClass('active');
              return;
            }
            li.removeClass('active');
          });
        }
      }
    };
  }
);

我看了@Stewei的解決方案。 但是,為此使用指令編寫解決方案對我來說毫無意義。 我認為,僅在創建組件時或在沖壓模板時才應編寫指令。 即使是為了淘汰模板,我也建議人們使用ng-include或類似的東西,除非您想要自定義元素提供的語義。

但是,我相信執行此操作的Angular方法是將行為邏輯與“特定於應用程序”的邏輯完全分開。 我認為您編寫指令的方式應使其獨立於周圍的控制器。

這是一個實際上可以解決此問題的工具,希望能以最“角度的方式”解決。 如果您可以對所有鏈接使用某種數據模型,並且可能對該模型進行ng-repeat,則可以進一步分離。 但這是開發人員的選擇。 由於您提到的是靜態頁面,因此此解決方案可能最適合。

http://plnkr.co/edit/DjaYi1ofpFKgKfhtakub?p=preview

在您最初的問題中,您確實詢問過是否可以將currentElement傳遞給getClass方法。 我之前曾問過這個問題,答案是否定的。 可以傳遞對currentElement的引用的唯一地方是在指令控制器中,但是目前這不在主題范圍內。

這是完成手頭任務的代碼。

HTML:

<div ng-controller="NavController">
  <ul >
    <li ng-class="getCategoryClass('A')">
        <a href="#">Category A</a>
        <ul>
            <li ng-class="getClass('a1.html','A')"><a href="a1.html">a1</a></li>
            <li ng-class="getClass('a2.html','A')"><a href="a2.html">a2</a></li>
        </ul>
    </li>
    <li ng-class="getCategoryClass('B')">
      <a href="#">Category B</a>
        <ul>
            <li ng-class="getClass('b1.html','B')"><a href="b1.html">b1</a></li>
            <li ng-class="getClass('b2.html','B')"><a href="b2.html">b2</a></li>
        </ul>
    </li>
    <li ng-class="getClass('contact.html','contact')"><a href="contact.html">contact</a></li>
  </ul>

  <input ng-model="currentPage" />
  <br>
  currentPage: {{currentPage}}
</div>

JS:

app.controller('NavController', 
    function($scope) {
      $scope.currentPage = "";
      $scope.currentCategory = "";
      $scope.pageActive = false;
      $scope.getClass = function(page,category){

        if( page === $scope.currentPage ) {
          $scope.pageActive = true;
          $scope.currentCategory = category;
          return "active";
        }
        else{
          return "";
        }
      };

      $scope.$watch('currentPage',function(val){
        $scope.pageActive = false;
      });

      $scope.onLinkClick = function($event){
        $event.preventDefault();  
      };

      $scope.getCategoryClass = function(category){
        return $scope.currentCategory === category && $scope.pageActive ? "active" : "";
      };
    }
  );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM