web-dev-qa-db-ja.com

AngularJS-HTML要素なしでng-ifを使用する方法

ng-ifディレクティブを持つトップHTML要素を表示しないようにAngularJSに指示する方法はありますか。 angular=子コンテンツのみを表示したい。

角度コード:

    <div ng-if="checked" id="div1">
      <div id="div2">ABC</div>
      <div id="div3">KLM</div>
      <div id="div4">PQR</div>
   </div>

レンダリングされたHTML:

   <div id="div1"> 
      <div id="div2">ABC</div>
      <div id="div3">KLM</div>
      <div id="div4">PQR</div>
   </div>

私が欲しいもの:

   <div id="div2">ABC</div>
   <div id="div3">KLM</div>
   <div id="div4">PQR</div>

ここにフィドルがあります。 http://jsfiddle.net/9mgTS/ 。欲しくない #div1 HTML。ただ欲しい #div2,3,4checkedtrueの場合。

可能な解決策は、ng-ifをすべての子要素に追加することですが、これはしたくありません。

55
waqas

現在文書化されていないディレクティブのペア、ng-if-startおよびng-if-end、これに使用できます。それらは、文書化された ng-repeat-startおよびng-repeat-end ディレクティブ、および必要に応じて ユニットテスト を確認できます。

たとえば、次のコードを考えます:

<ul>
  <li ng-if-start="true">a</li>
  <li>b</li>
  <li>c</li>
  <li ng-if-end>d</li>
  <li ng-if-start="false">1</li>
  <li>2</li>
  <li>3</li>
  <li ng-if-end>4</li>
</ul>

最初の4つのlisが表示され、最後の4つのlisが非表示になります。

CodePenのライブ例を次に示します。 http://codepen.io/anon/pen/PqEJYV

もあります ng-show-startおよびng-show-end期待どおりに機能するディレクティブ。

50
Mark Amery

カスタムディレクティブを作成したい場合は、ng-ifをプログラムで子に適用し、プロセスでDOMをフラット化できます。

指令コード:

.directive('ngBatchIf', function() {
    return {
        scope: {},
        compile: function (Elm, attrs) {
            // After flattening, Angular will still have the first element
            // bound to the old scope, so we create a temporary marker 
            // to store it
            Elm.prepend('<div style="display: none"></div>');

            // Flatten (unwrap) the parent
            var children = Elm.children();
            Elm.replaceWith(children);

            // Add the ng-if to the children
            children.attr('ng-if', attrs.ngBatchIf);

            return {
                post: function postLink(scope, Elm) {
                    // Now remove the temporary marker
                    Elm.remove();
                }
            }
        }
    }
})

角度コード:

<div id="div1" ng-batch-if="checked">
    <div id="div2">ABC</div>
    <div id="div3">KLM</div>
    <div id="div4">PQR</div>
</div>

レンダリングされたHTML:

<div id="div2" ng-if="checked">ABC</div>
<div id="div3" ng-if="checked">KLM</div>
<div id="div4" ng-if="checked">PQR</div>

フィドル: http://jsfiddle.net/o166xg0s/4/

7
seanhodges

親divを使用したくない理由がわかりませんが、+ 20 divがある場合、これは良い解決策になります。

[〜#〜] html [〜#〜]

   <div ng-repeat="div in divs" ng-if="checked" id="{{div.name}}">{{div.content}}</div>

[〜#〜] js [〜#〜]

app.controller('myCtrl', function($scope) {
    $scope.checked = true;
    $scope.divs = {
         {'name': 'div2', content:'ABC'},
         {'name': 'div3', content:'KLM'},
         {'name': 'div4', content:'PQR'}
    }
});
0
VinEzhu

Angular 1.21ソリューション:

HTML:

<div ng-app="app" ng-controller="ctrl">
    <div ng-iff="checked" id="div1">
        <div id="div2">ABC</div>
        <div id="div3">KLM</div>
        <div id="div4">PQR</div>
    </div>
    <button ng-click="toggleCheck()">Toggle Check</button>
</div>

JAVASCRIPT:

angular.module('app', []).
controller('ctrl', function ($scope) {
    $scope.checked = true;

    $scope.toggleCheck = function () {
        $scope.checked = !$scope.checked;
    };
}).
directive('ngIff', function ($compile) {
    return {
        compile: function compile(tElement, tAttrs, transclude) {
            return {
                pre: function preLink(scope, iElement, iAttrs, controller) {
                    var bindingElem = iElement.attr('ng-iff');
                    var children = iElement.children();

                    angular.forEach(children,function(c){
                        angular.element(c).attr('ng-if',bindingElem);
                    });

                    $compile(children)(scope, function(newElem){
                        iElement.replaceWith(newElem);
                    });
                }
            };
        }
    };
});

[〜#〜] jsfiddle [〜#〜]

0
Amir Popovich