Как предварительно загрузить представления angular2, чтобы при первой загрузке не мерцала белая страница?

Я создаю приложение angular 2 на простом JS. Моя проблема в том, что когда я перехожу со страницы на другую, она мерцает белой страницей, пока не будет отображено новое представление. Это происходит для всех компонентов только при первом доступе к ним. Если я иду по тому же маршруту во второй раз, страница загружается без белой страницы. Я делаю снимок экрана, чтобы лучше объяснить свою проблему: https://drive.google.com/file/d/0B5pOsXT-4rdTbmtuVnlUdXRMdE0/view?usp=sharing

Вот мой основной вид:

<router-outlet></router-outlet>

<nav id="menu">
    <a [routerLink]="['Page1']">Page 1</a>
    <a [routerLink]="['Page2']">Page 2</a>
    <a [routerLink]="['Page3']">Page 3</a>
    <a [routerLink]="['Page4']">Page 4</a>
    <a [routerLink]="['Page5']">Page 5</a>
</nav>

RouteConfig определяется следующим образом:

AppComponent = ng.router
    .RouteConfig([
        {path: '/page1', name:"Page1", component: Page1Component, useAsDefault: true },
        {path: '/page2', name:"Page2", component: Page2Component},
        ...
    ])
    (AppComponent);

И все мои компоненты имеют файл .html и файл .css, например:

Page1Component = ng.core
    .Component({
        selector: 'rl-page1',
        templateUrl: 'app/components/page1/view.html',
        styleUrls: ['app/components/page1/style.css'],
        directives: [ng.router.ROUTER_DIRECTIVES]
    })
    .Class({
        constructor: [ng.router.Router, function(router) {
            this.router = router;


        }]
    });

Судя по тому, что страницы углового кеша после того, как я к ним обращаюсь, и при втором доступе будут отображаться мгновенно (без мерцания белого). Я ищу, как я могу предварительно загрузить это, но я не могу найти никакого ответа или метода по этому поводу.

Пожалуйста, дайте мне знать, если вам нужно больше кода.

(Я не использую Page1, Page2 в реальном приложении, только для этого вопроса я изменил, например, чтобы он был более понятным)

Спасибо.

РЕДАКТИРОВАНИЕ: 18 марта 2016 г.

Я пытаюсь использовать DynamicComponentLoader для загрузки всех компонентов в скрытом div. Код выглядит так в AppComponent:

ngOnInit: function(){
    this.dcl.loadIntoLocation(Page1Component, this.elementRef, 'preloadpages');
    this.dcl.loadIntoLocation(Page2Component, this.elementRef, 'preloadpages');
},

и html, куда загружается: <div style="display: none;"><div #preloadpages></div></div>

Но столкнулся с 2 проблемами:

  1. Если один из моих компонентов имеет в конструкторе RouteParams вот так:

    конструктор: [ng.router.RouteParams, function(routeParam) { ... }], я получаю эту ошибку: EXCEPTION: No provider for RouteParams! (class19 -> RouteParams)

  2. Все компоненты загружаются так же, как вы его открываете. Если у меня есть вызов ajax в конструкторе, создается вызов ajax, и все компоненты html будут добавлены в мой скрытый div. Здесь может быть проблема с производительностью, если при запуске я пытаюсь загрузить около 5 компонентов, а некоторые делают вызовы ajax. Я ищу, есть ли решение для загрузки только html + css или для отправки флага конструктору компонента, чтобы знать, что я загружаю скрытый только для проповеди.

Спасибо.


person Daniel Dudas    schedule 26.02.2016    source источник


Ответы (2)


Перефразируя https://stackoverflow.com/a/37298914/441662

Проблема в том, что файлы загружаются отдельно, что можно предотвратить с помощью чего-то вроде веб-пакета, который компилирует исходники в пакеты, которые могут включать как ваше приложение, так и шаблоны, используемые в маршрутах. (хотя я до сих пор не могу объяснить прыжок в начало страницы).

Вот как вы можете изменить конфигурацию веб-пакета проекта angular/angular2-seed:

пакет.json

"devDependencies": {
  ...,
  "html-loader": "^0.4.3",
},

webpack.config.js

module: {
  loaders: [
    ...,
    { test: /\.html$/, loader: 'html' }
  ]
}

Пример использования в your-component.ts

@Component({
  template: require('app/components/your-component/your-component.html')
})

Теперь маршруты загружаются моментально, никаких мерцаний и прыжков не происходит.

person Benny Bottema    schedule 17.05.2016

Добавьте обертку вокруг <router-outlet>

<div [hidden]="!isInitialized">
  <router-outlet></router-outlet>
</div>

В компоненте страницы установите isInitialized на false. Тогда позвони

this.router.navigate(['Page1'])
.then(_ => this.router.navigate(['page2']))
.then(_ => this.router.navigate(['page3']))
...
.then(_ => {
    this.isInitialized = true; 
    this.router.navigate(['Page1']);
});
person Günter Zöchbauer    schedule 26.02.2016
comment
Привет. Наконец-то мне удалось сделать рабочую версию этого. Если я пытаюсь загрузить только 1 страницу, все работает нормально. Если я пытаюсь загрузить более 1, я получаю сообщение об ошибке. Вот html: <div style="display: none;"><div #preloadpages></div></div> и для загрузки компонента я вызываю this.dcl.loadIntoLocation(Page1Component, this.elementRef, 'preloadpages'); и this.dcl.loadIntoLocation(Page2Component, this.elementRef, 'preloadpages'); для второго компонента. И я получаю сообщение об ошибке: EXCEPTION: No provider for RouteParams! (class19 -> RouteParams) Что-то очень общее. - person Daniel Dudas; 18.03.2016
comment
У вас есть RouteParams в качестве параметра в одном из компонентов? - person Günter Zöchbauer; 18.03.2016
comment
Да. У меня в конструкторе что-то вроде этого: constructor: [ng.router.Router, ... function(router,...) { ... } - person Daniel Dudas; 18.03.2016
comment
На самом деле на 2-й мысли. Я не думаю, что мой ответ - хороший подход. - person Günter Zöchbauer; 18.03.2016
comment
Привет. Спасибо за обновление. В этом новом способе я вижу, что мне нужно сначала перемещаться по всем страницам. У меня есть сома-страницы, которые доступны, например, только со страницы 3 (давайте назовем ее страницей 3-1). Поэтому я подумал о предварительной загрузке страницы 3-1 (доступной только со страницы 3) только тогда, когда пользователь переходит на страницу 3. Поэтому я не загружаю в начале страницы, к которым пользователь не может получить доступ в один клик из дома. - person Daniel Dudas; 18.03.2016
comment
Мне трудно понять, что имело бы смысл в вашем сценарии. Я просто попытался объяснить основную идею, стоящую за этим. Просто перейдите к страницам, которые вы действительно хотите предварительно загрузить. Я также только что увидел, что у меня была ошибка, извините. Это не работает с *ngIf. Вместо этого используйте [hidden]=".." (уже исправлено в моем ответе) - person Günter Zöchbauer; 18.03.2016
comment
Спасибо за помощь. Я сделаю тесты и посмотрю, что быстрее и потребляет меньше памяти. - person Daniel Dudas; 18.03.2016
comment
Этот подход не сработал для меня, но я придумал новый ( stackoverflow.com/questions/37286283/ ). - person Benny Bottema; 18.05.2016