68

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

4

6 回答 6

148

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

文档: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 元素在这个控制器之外,你可以使用$rootScopeevents做同样的事情。

于 2013-08-08T18:34:43.307 回答
8

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

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

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

更新

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

  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();
      });

    }
  }
});

在您的元素中粘贴(加载时显示),并在您的控制器中注入 $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 回答
0

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

于 2016-03-28T21:06:04.773 回答