68

データがサーバーから返される前に、HTML にちらつきが発生する Angularjs の問題があります。

この問題を示すビデオを次に示します: http://youtu.be/husTG3dMFOM - #| に注意してください。そして右側の灰色の領域。

私は ngCloak を試しましたが成功しませんでした (ただし、ngCloak はブラケットが約束どおりに表示されないようにします)。HTML が Angular によって読み込まれるまでコンテンツを非表示にする最良の方法を考えています。

コントローラーで次のコードを使用して動作するようにしました。

var caseCtrl = function($scope, $http, $routeParams) {
    $('#caseWrap').hide(); // hides when triggered using jQuery
    var id = $routeParams.caseId;

    $http({method: 'GET', url: '/v1/cases/' + id}).
        success(function(data, status, headers, config) {                   
            $scope.caseData = data;

            $('#caseWrap').show(); // shows using jQuery after server returns data
        }).
        error(function(data, status, headers, config) {
            console.log('getCase Error', arguments);
        });
}

...しかし、コントローラーからDOMを操作しないように何度も聞いています。私の質問は、ディレクティブを使用してこれを達成するにはどうすればよいですか? つまり、すべてのコンテンツがサーバーから読み込まれるまで、ディレクティブが関連付けられている要素を非表示にするにはどうすればよいでしょうか?

4

6 に答える 6

148

CSSに以下を追加します。

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
  display: none !important;
}

次のように、「 ng-cloak 」属性を divに追加するだけです。

<div id="template1" ng-cloak>{{scoped_var}}<div>

ドキュメント: https://docs.angularjs.org/api/ng/directive/ngCloak

于 2014-08-30T21:30:27.700 に答える
10

caseWrap 要素で、配置ng-show="contentLoaded"してから、現在配置している場所に$('#caseWrap').show();配置します$scope.contentLoaded = true;

caseWrap 要素がこのコントローラーの外にある場合、$rootScopeまたはeventsを使用して同じ種類のことを行うことができます。

于 2013-08-08T18:34:43.307 に答える
8

以下を CSS に追加します。

[ng\:cloak],[ng-cloak],.ng-cloak{display:none !important}

angular テンプレートのコンパイルが十分に速く行われていません。

アップデート

コントローラーで DOM 操作を行うべきではありません。できることは 2 つあります... 1. ディレクティブを使用して、コントローラーのスコープ内で値の変更をインターセプトできます。あなたの場合、監視したいプロパティが割り当てられた属性としてディレクティブを作成します。あなたの場合、それはcaseData. casedata が falsey の場合は非表示にします。それ以外の場合は、表示します。

  1. より簡単な方法は、ngShow='casedata' を使用することです。

コード

var myApp = angular.module('myApp', []);
myApp.controller("caseCtrl", function ($scope, $http, $routeParams, $timeout) {
    $scope.caseData = null;
    //mimic a delay in getting the data from $http
    $timeout(function () {
        $scope.caseData = 'hey!';
    }, 1000);

})
    .directive('showHide', function () {
    return {
        link: function (scope, element, attributes, controller) {
            scope.$watch(attributes.showHide, function (v) {
                if (v) {
                    element.show();
                } else {
                    element.hide();
                }
            });
        }
    };
});

HTML

<div ng-controller='caseCtrl' show-hide='caseData'>using directive</div>
<div ng-controller='caseCtrl' ng-show='caseData'>using ngShow</div>

JSFIDDLE: http://jsfiddle.net/mac1175/zzwBS/

于 2013-08-08T18:28:57.120 に答える
2

指示を求めたので、これを試してください。

.directive('showOnLoad', function() {
  return {
    restrict: 'A',
    link: function($scope,elem,attrs) {

      elem.hide();

      $scope.$on('show', function() {
        elem.show();
      });

    }
  }
});

要素に貼り付け (show-on-load)、コントローラーに $rootScope を挿入し、html が読み込まれたときにこのブロードキャスト イベントを使用します。

$rootScope.$broadcast('show');
于 2013-08-08T18:49:20.653 に答える
1

Zack の応答を使用して、「読み込み」ディレクティブを作成しました。これは、一部の人にとって役立つ可能性があります。

テンプレート:

<script id="ll-loading.html" type="text/ng-template">
  <div layout='column' layout-align='center center'>
    <md-progress-circular md-mode="indeterminate" value="" md-diameter="52"></md-progress-circular>
  </div>
</script>

指令:

    directives.directive('loading', function() {
  return {
    restrict: 'E',
    template: 'll-loading.html',
    link: function($scope,elem,attrs) {

      elem.show();

      $scope.$on('loaded', function() {
        console.log("loaded: ");
        elem.hide();
      });

    }
  }
});

この例では、html で angular-material を使用しています

于 2015-12-22T16:52:48.417 に答える