2016-01-06 10 views
9

Moja obecna implementacja:kątowe kod uniknąć powielania przy użyciu `NG-if`

<div class="outer-class" ng-repeat="item in items"> 
    <div class="inner-class" ng-if="isShow"> 
    <div class="inner-class-1">{{item}}</div> 
    </div> 
    <div ng-if="!isShow" class="inner-class-1">{{item}}</div> 
</div> 

Powyższy kod działa, ale jest dużo kodu powtórzenia:

  1. ng-if jest tam dwa razy (ng-switch nie może być używany od momentu wprowadzenia nowego elementu)
  2. <div ng-if="!isShow" class="inner-class-1">{{item}}</div> Powtarza się dwa razy, tylko dlatego, że nie chcę, aby element (<div class="inner-class"></div>) hermetyzował moje dane, gdy ng-if jest wartością false.

Zastanawiałem się, czy nie jest lepszy sposób na ponowne napisanie tego samego.

+0

Nie chcesz element wewnętrzny klasy-1 mają być zapakowane w innym elementem wszystkich razem lub po prostu nie mają rodzica z klasy wewnętrznej klasy ? – Nora

+0

Nie chcę, aby element 'inner-class-1' był obecny, gdy moje wyrażenie ng-if jest fałszywe. –

+0

Myślę, że byłoby lepiej, aby zmienić swój styl CSS, aby styl i zachowanie, które chcesz przełączać, można było zrobić w oparciu o istnienie klasy "wewnętrznej klasy". Chodzi mi o to, że obecność owijającego diva wcale nie robi różnicy, tylko sama klasa powinna zmieniać rzeczy. – ste2425

Odpowiedz

1

W tym przypadku byłoby lepiej wyłączyć tworzenie dyrektywę niestandardowe, które mogą warunkowo zawinąć zawartości. Można zrobić coś takiego:

angular.module('demo', []).controller('DemoController', function($scope) { 
 
    $scope.items = [1, 2, 3]; 
 
    $scope.isShow = false; 
 
}) 
 

 
.directive('wrapIf', function() { 
 
    return { 
 
    restrict: 'A', 
 
    transclude: true, 
 
    link: function(scope, element, attrs, controller, transclude) { 
 

 
     var previousContent; 
 

 
     scope.$watch(attrs.wrapIf, function(newVal) { 
 
     if (newVal) { 
 
      previousContent.parent().append(element); 
 
      element.empty().append(previousContent); 
 
     } else { 
 
      transclude(function(clone, scope) { 
 
      previousContent = clone; 
 
      element.replaceWith(clone); 
 
      }); 
 
     } 
 
     }) 
 
    } 
 
    }; 
 
});
.inner-class, .inner-class-1 { 
 
    padding: 6px; 
 
    background: #DDD; 
 
} 
 
.inner-class-1 { 
 
    background: #34dac3; 
 
} 
 
.outer-class { 
 
    margin-bottom: 6px; 
 
}
<script src="https://code.angularjs.org/1.4.8/angular.js"></script> 
 

 
<div ng-app="demo" ng-controller="DemoController"> 
 

 
    <p> 
 
    <button ng-click="isShow = !isShow">Toggle isShow ({{ isShow }})</button> 
 
    </p> 
 

 
    <div class="outer-class" ng-repeat="item in items"> 
 
    <div class="inner-class" wrap-if="isShow"> 
 
     <div class="inner-class-1" ng-click="test(item)">{{item}}</div> 
 
    </div> 
 
    </div> 
 

 
</div>

+0

Czy nie byłoby zabójcą wydajności używać obserwatora wewnątrz 'ng-repeat'? –

+0

Niezupełnie, jeśli użyjesz go mądrze. ngJeśli robi to samo: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js Ale nie chodzi o dyrektywę wrapIf, jeśli chodzi o sposób jej użycia (niekoniecznie z ngRepeat) i co robi. – dfsq

+0

O tak, '::' - jeden czas wiązania może mi tutaj pomóc. 'wrap-if =" :: isShow "' –

1

Może coś takiego?

//optional wrapper 
 

 
function resolveTemplate(tElement, tAttrs) { 
 
    if (tAttrs.showWrapper){ 
 
    return "<div ng-class='wrapperClass' ng-transclude></div>" 
 
    } 
 
    else return "<ng-transclude></ng-transclude>"; 
 
} 
 

 
app.directive('optionalWrapper', function() { 
 
    return { 
 
     restrict: 'E', 
 
     transclude: true, 
 
     template: resolveTemplate, 
 
     link: function($scope, el, attrs) { 
 
      $scope.wrapperClass = attrs.wrapperClass; 
 
     } 
 
    }; 
 
});

Aby być stosowany tak:

<optional-wrapper wrapper-class='inner-class-1' show-wrapper='isShow'></optional-wrapper>

+0

To rozwiązanie nie działa dobrze, tak myślę. Po pierwsze, dyrektywa nie nadaje się do ponownego użycia, ponieważ szablon jest zakodowany na stałe. Następnie "show-wrapper" jest używany jako atrybut, który nie pozwala warunkowo zmieniać zawijania. W końcu używa jeszcze jednego opakowania, które nie jest zbyt wygodne dla celów dyrektywy. – dfsq

Powiązane problemy