Angular.js-隐藏内容直到加载DOM


67

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


嘿,我认为这个答案应该已经被接受了;)stackoverflow.com/a/25586922/3437790
塞巴斯蒂安·霍林2015年

Answers:


143

在您的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


3
ng-cloak!唯一的是:)
bresleveloper

4
很好,为我节省了很多丑陋的麻烦
Demodave

5
非常感谢。Angular文档尚不清楚,似乎他们说CSS已经被嵌入了,但是还没有。谢谢你的提示!
alcfeoh

尼斯,已解决:)
PHP Ninja


8

将以下内容添加到您的CSS中:

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

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

更新

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

  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/


1
@ScottyBollinger我也应该告诉您不要在控制器中进行DOM操作。这被认为是一种不好的做法,而不是。(请参阅docs.angularjs.org/guide/dev_guide.mvc.understanding_controller中的“正确使用控制器” )。我将尽快更新有关如何解决此问题的答案...
mitch

2

由于您要求的指令,请尝试此。

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

      elem.hide();

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

    }
  }
});

粘贴(在加载时显示)在您的元素中,并在控制器中注入$ rootScope,并在html加载后使用此广播事件。

$rootScope.$broadcast('show');

感谢您的回复。上面的答案更有效。我只要求一个新指令,因为我不知道可以使用ngShow指令来实现。
Scotty Bollinger

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


0

接受的答案对我不起作用。我有一些具有ng-show指令的元素,即使使用ng-cloak,这些元素仍会暂时显示。在ng-show返回false之前,似乎已解决了ng-cloak。在我的元素中添加ng-hide类可以解决我的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.