Предотвратите кратковременное отображение двойной фигурной скобки до того, как angular.js скомпилирует / интерполирует документ

298

Кажется, это в первую очередь проблема в IE, когда нужно загрузить несколько изображений / сценариев, может быть достаточно времени, когда литерал {{stringExpression}}в разметке будет отображаться, а затем исчезнет, ​​когда angular завершится с его компиляцией / интерполяцией документ.

Существует ли распространенная причина, по которой это могло бы произойти, которая указала бы, что я делаю что-то в целом неправильно, или есть известный способ предотвратить это?

JeremyWeir
источник
6
Это может помочь: branchandbound.net/blog/web/2013/08/some-angularjs-pitfalls
Исмаэль
Выше было правильное решение
Эдмунд Рохас

Ответы:

283

Я думаю, что вы ищете ngCloakдирективу: https://docs.angularjs.org/api/ng/directive/ngCloak

Из документации:

Директива ngCloak используется для предотвращения краткого отображения HTML-шаблона Angular браузером в исходном (некомпилированном) виде во время загрузки приложения. Используйте эту директиву, чтобы избежать нежелательного эффекта мерцания, вызванного отображением HTML-шаблона.

Директива может быть применена к <body>элементу, но предпочтительным является применение нескольких ngCloak директив к небольшим частям страницы, чтобы обеспечить прогрессивную визуализацию представления браузера.

pkozlowski.opensource
источник
1
Чтобы избежать необработанного Angular HTML-кода, это ngCloakшироко распространенная практика? Это кажется легким делом, но я не опытен в AngularJS.
Кевин Мередит
32
Я не думаю, что это будет работать, если вы загрузите все сценарии в конце тела.
trusktr
8
Аааа, подождите, nvm, ответ LOAS - это решение, если вы загружаете скрипты последними. Используйте класс .ng-плащ.
trusktr
3
Загрузите скрипт angularjs в <head>разделе html, ngCloakчтобы быть эффективными.
Мустафа
1
Я могу подтвердить, что это работает отлично, если я загружаю angular.jsв <head>разделе моей страницы.
Арон Лоринц
197

Также вы можете использовать <span ng-bind="hello"></span>вместо {{hello}}.

http://jsfiddle.net/4LhN9/34/

Эндрю Джослин
источник
94
Одна из особенностей ng-bind, которая иногда упускается из виду, заключается в том, что вы можете указать текст, отображаемый во время загрузки Angular: <span ng-bind = "myScopeProperty"> loading ... </ span>. появится «загрузка ...», а затем будет заменена после определения myScopeProperty.
Марк Райкок
@MarkRajcok: спасибо за совет! Я понятия не имел. Это очень просто и элегантно и решает проблему, с которой я сам столкнулся.
Джим Раден
9
Если вам нужно несколько выражений, используйте ngBindTemplate. Например, <span ng-bind-template = "{{scopeProperty1}} {{scopeProperty2}}"> загрузка ... </ span>
Марк Райкок
27
Вы также можете сделать {{привет || 'loading ...'}}
Эндрю Джослин
5
@AndyJoslin Отлично. При таком подходе сценарий углового js должен находиться в голове, а не в нижней части страницы, чтобы выражение {{}} не мигало при загрузке страницы.
s_t_e_v_e
51

Чтобы повысить эффективность подхода class = 'ng-cloak', когда скрипты загружаются последними, убедитесь, что в заголовке документа загружен следующий css:

.ng-cloak { display:none; }
Loas
источник
4
Добавление! Важно не плохая идея также.
eomeroff
12
Не visibility: hiddenбудет лучше?
mpen
2
@eomeroff, но !importantэто хакер CSS (плохая вещь) для продвижения стиля, который будет выбран, верно? Это нарушает правила выбора CSS.
Кевин Мередит
5
ИМХО это один из случаев! Важно было ввести.
lex82
3
@Mark Я бы предположил, что «visibility: hidden» все равно будет отображать пространство, необходимое для разметки шаблона, тогда как «display: none» вообще ничего не отображает. Если скрыта только видимость, любые внешние элементы могут внезапно свернуть до истинного внутреннего размера, вместо того, чтобы увеличиваться в размере из ничего. Я полагаю, это то, что вы предпочитаете. :)
Джеймс Уилкинс
40

Просто добавьте скрывающий CSS в заголовок страницы или в один из ваших CSS-файлов:

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

Затем вы можете использовать директиву ngCloak в соответствии с обычной практикой Angular, и она будет работать даже до загрузки самого Angular.

Это именно то, что делает Angular: код в конце angular.js добавляет вышеуказанные правила CSS к заголовку страницы.

Беннет МакЭлви
источник
+1 Я сам придумал [ngcloak]селектор, но это более полно.
Пьер Генри
1
Отличный ответ! Я загружаю Angular в конце своего тела, поэтому ngCloak недоступен, и он по-прежнему мигает {{}}. Это исправило это.
Скотти
21

В вашем CSS добавить следующее

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

И тогда в вашем коде вы можете добавить директиву ng-cloak. Например,

<div ng-cloak>
   Welcome {{data.name}}
</div>

Это оно!

Натан Сеневиратне
источник
3

Я согласен с ответом @ pkozlowski.opensource, но у меня не работает класс ng-clock для использования с ng-repeat. поэтому я хотел бы порекомендовать вам использовать класс для простого выражения-разделителя, такого как {{name}} и директива ngCloak для ng-repeat.

<div class="ng-cloak">{{name}}<div>

и

<li ng-repeat="item in items" ng-cloak>{{item.name}}<li>
Jaison
источник
Спасибо, что заметили меня ошибку
Jaison