Angularjs - 在加载DOM之前隐藏内容

时间:2013-08-08 18:24:52

标签: angularjs

我在Angularjs中遇到一个问题,在我的数据从服务器返回之前,我的HTML中有一个闪烁。

以下是展示此问题的视频:http://youtu.be/husTG3dMFOM - 请注意#|和右边的灰色区域。

我尝试过ngCloak没有成功(尽管ngCloak确实阻止括号出现在承诺中)并且想知道在Angular填充HTML之前隐藏内容的最佳方法。

我让它在我的控制器中使用此代码:

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。我的问题是如何使用指令实现这一目标?换句话说,在从服务器加载所有内容之前,如何隐藏指令所附加的元素?

6 个答案:

答案 0 :(得分:127)

CSS 中添加:

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

只需在此处为您的div添加“ ng-cloak ”属性:

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

doc:https://docs.angularjs.org/api/ng/directive/ngCloak

答案 1 :(得分:9)

在你的caseWrap元素上,放置ng-show="contentLoaded",然后放置$('#caseWrap').show();放置$scope.contentLoaded = true;

的位置

如果caseWrap元素在此控制器之外,您可以使用$rootScopeevents执行相同类型的操作。

答案 2 :(得分:8)

将以下内容添加到CSS中:

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

编辑角度模板的速度不够快。

更新

您不应该在控制器中执行DOM操作。你可以做两件事...... 1.您可以通过指令拦截控制器范围内值的更改!在您的情况下,创建一个指令作为分配了您要监视的属性的属性。在您的情况下,它将是caseData。如果casedata是假的,请隐藏它。否则,请显示它。

  1. 更简单的方法就是使用ngShow ='casedata'。
  2. 代码

    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/

答案 3 :(得分: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');

答案 4 :(得分:1)

我已经使用Zack的回复来创建一个“加载”#39;指令,对某些人可能有用。

模板:

<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

答案 5 :(得分:0)

接受的答案对我没有用。我有一些具有ng-show指令的元素,即使使用ng-cloak,元素仍会暂时显示。看来ng-cloak在ng-show返回false之前已经解决了。将ng-hide类添加到我的元素中解决了我的问题。