Корневой компонент отображается в розетке маршрутизатора

Вот структура проекта angular 2 js (ES2015):

src ├── app.js ├── components │   ├── app │   ├── index.js │   ├── list │   ├── loess │   └── nw ├── modules │   ├── app.module.js │   └── index.js ├── routes │   ├── app.routes.js │   └── index.js └── vendor.js

Я не могу понять, как использовать тег розетки маршрутизатора. Когда я использую его в шаблоне корневого компонента, тег заставляет этот компонент отрисовываться дважды, заменяя тег выхода маршрутизатора. Простите за тавтологию. Вдобавок к этому у меня ошибка: Uncaught (in promise): SyntaxError: Failed to execute 'add' on 'DOMTokenList': The token provided must not be empty.

Вот изображение с обработанным содержимым.

Это оригинальная трассировка стека:

angular.vendor.js:2723ORIGINAL STACKTRACE:ErrorHandler.handleError @ angular.vendor.js:2723next @ angular.vendor.js:3586schedulerFn @ angular.vendor.js:3341SafeSubscriber.__tryOrUnsub @ angular.vendor.js:4971SafeSubscriber.next @ angular.vendor.js:4926Subscriber._next @ angular.vendor.js:4880Subscriber.next @ angular.vendor.js:4844Subject.next @ angular.vendor.js:4451EventEmitter.emit @ angular.vendor.js:3341onError @ angular.vendor.js:3421onHandleError @ angular.vendor.js:3349ZoneDelegate.handleError @ angular.vendor.js:24550Zone.runGuarded @ angular.vendor.js:24468_loop_1 @ angular.vendor.js:24709drainMicroTaskQueue @ angular.vendor.js:24717ZoneTask.invoke @ angular.vendor.js:24639 2016-10-15 22:29:01.285 angular.vendor.js:2723Error: Uncaught (in promise): SyntaxError: Failed to execute 'add' on 'DOMTokenList': The token provided must not be empty. at resolvePromise (angular.vendor.js:24762) at angular.vendor.js:24796 at ZoneDelegate.invokeTask (angular.vendor.js:24572) at Object.onInvokeTask (angular.vendor.js:3347) at ZoneDelegate.invokeTask (angular.vendor.js:24572) at Zone.runTask (angular.vendor.js:24488) at drainMicroTaskQueue (angular.vendor.js:24699) at XMLHttpRequest.ZoneTask.invoke (angular.vendor.js:24639)ErrorHandler.handleError @ angular.vendor.js:2723next @ angular.vendor.js:3586schedulerFn @ angular.vendor.js:3341SafeSubscriber.__tryOrUnsub @ angular.vendor.js:4971SafeSubscriber.next @ angular.vendor.js:4926Subscriber._next @ angular.vendor.js:4880Subscriber.next @ angular.vendor.js:4844Subject.next @ angular.vendor.js:4451EventEmitter.emit @ angular.vendor.js:3341onError @ angular.vendor.js:3421onHandleError @ angular.vendor.js:3349ZoneDelegate.handleError @ angular.vendor.js:24550Zone.runGuarded @ angular.vendor.js:24468_loop_1 @ angular.vendor.js:24709drainMicroTaskQueue @ angular.vendor.js:24717ZoneTask.invoke @ angular.vendor.js:24639

vendor.js:

//Polyfill
import '../node_modules/core-js';
import '../node_modules/zone.js';
import '../node_modules/reflect-metadata';
import '../node_modules/system';
//Dependencies
import '../node_modules/rxjs';

// Core
import '../node_modules/@angular/platform-browser';
import '../node_modules/@angular/platform-browser-dynamic';
import '../node_modules/@angular/forms';
import '../node_modules/@angular/http';
import '../node_modules/@angular/router';
import '../node_modules/@angular/core';
import '../node_modules/@angular/common';
import '../node_modules/@angular/compiler';

//jQuery
import '../node_modules/jquery';
//Bootstrap
import '../node_modules/bootstrap';
//Bootstrap sidebar
import '../node_modules/bootstrap-layout';
//Bootstrap slider
import '../node_modules/bootstrap-slider';

app.js:

import { platformBrowserDynamic } from '../node_modules/@angular/platform-browser-dynamic';

import { AppModule } from "./modules/app.module";

platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.log(err));

app.module.js:

import { BrowserModule } from '../../node_modules/@angular/platform-browser';
import { FormsModule } from '../../node_modules/@angular/forms';
import { HttpModule } from '../../node_modules/@angular/http';
import { RouterModule } from '../../node_modules/@angular/router';
import { NgModule } from '../../node_modules/@angular/core';

import { AppComponent, NwComponent, LoessComponent } from '../components';
import { routes } from '../routes';


export let AppModule = NgModule({
              imports: [ BrowserModule, FormsModule, HttpModule, RouterModule.forRoot(routes) ],
              declarations: [ AppComponent, NwComponent, LoessComponent ],
              bootstrap: [ AppComponent ]
            }).Class({
              constructor() {
                console.log("Module started");
              }
            });

маршруты / app.routes.js:

import { provideRoutes } from '../../node_modules/@angular/router'
import { AppComponent, LoessComponent, NwComponent } from '../components';

export let routes = [
   { path: 'loess', component: LoessComponent },
   { path: 'nw', component: NwComponent },
   { path: '', component: AppComponent }, // default route
   { path: '**', redirectTo: '/home', pathMatch: 'full' } // 404
];

export let routesProvider = [
    provideRoutes(routes)
];

компоненты / приложение / app.component.js:

import '../../../node_modules/jquery';
import { Component, Inject } from '../../../node_modules/@angular/core';
import { BootstrapLayout, sidebar } from '../../../node_modules/bootstrap-layout';
import { ROUTER_DIRECTIVES } from '../../../node_modules/@angular/router';

export let AppComponent =
        Component({
          selector: 'ml-index',
          templateUrl: '/client/js/src/components/app/app.html',
        })
        .Class({
          constructor() {
            this.title = "App Component";

            console.log("AppComponent init");
            sidebar.init('#ml-sidebar');
          }
        });

app.html:

<h1>{{title}}</h1>
<router-outlet></router-outlet>

Я также использую [email protected]. Вот конфигурационный файл:

var webpack = require("./node_modules/webpack");
var HtmlWebpackPlugin = require("./node_modules/html-webpack-plugin")

module.exports = {
    context: __dirname,
    entry: {
        app: './src/app.js',
        vendor: './src/vendor.js'
    },
    module: {
        loaders: [
            { test: /\.js$/ , loader: 'babel-loader' },
            { test: /\.css$/, loaders: ['style-loader','css-loader','resolve-url'] },
            { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, loader : 'file?name=assets/[name].[hash].[ext]'},
            { test: /\.html$/, loader: 'html' },
        ]
    },
    output: {
        path: __dirname+'/bundle',
        filename: 'angular.[name].js'
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: ['app', 'vendor', 'polyfills']
        }),
        new HtmlWebpackPlugin({
            template: '../index.html'
        }),
        new webpack.ProvidePlugin({
            jQuery: 'jquery',
            $: 'jquery',
            jquery: 'jquery'
        }),
    ]
};

P.S: После предоставления рабочего решения ниже появилась еще одна ошибка: Uncaught (in promise): SyntaxError: Failed to execute 'add' on 'DOMTokenList': The token provided must not be empty..

Вот описание трассировки стека:

ErrorHandler.handleError    @   angular.vendor.js:2723
next    @   angular.vendor.js:3586
schedulerFn @   angular.vendor.js:3341
SafeSubscriber.__tryOrUnsub @   angular.vendor.js:4971
SafeSubscriber.next @   angular.vendor.js:4926
Subscriber._next    @   angular.vendor.js:4880
Subscriber.next @   angular.vendor.js:4844
Subject.next    @   angular.vendor.js:4451
EventEmitter.emit   @   angular.vendor.js:3341
onError @   angular.vendor.js:3421
onHandleError   @   angular.vendor.js:3349
ZoneDelegate.handleError    @   angular.vendor.js:24550
Zone.runGuarded @   angular.vendor.js:24468
_loop_1 @   angular.vendor.js:24709
drainMicroTaskQueue @   angular.vendor.js:24717
ZoneTask.invoke @   angular.vendor.js:24639
2016-10-16 00:04:40.401

Я решил это. Извини, это моя вина. Ошибка возникла из-за недопустимого синтаксиса маршрутов в app.html.


person Max Yakovenko    schedule 15.10.2016    source источник


Ответы (1)


Это потому, что путь '' сопоставлен с AppComponent.

С линией

platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.log(err));
  • Вы говорите Angular визуализировать AppComponent при запуске приложения.
  • AppComponent запускается и проверяет текущий маршрут.
  • Находит '' как текущий маршрут и компонент приложения для загрузки в '' маршруте. Таким образом создается еще один компонент приложения и загружается в розетку маршрутизатора.

Решение:

Создайте что-то вроде HomePageComponent и сопоставьте его с маршрутом.

person Sefa    schedule 15.10.2016
comment
Большое спасибо, довольно четкое объяснение. Пожалуйста, поправьте меня, если я ошибаюсь. Когда мы загружаем модуль, у нас должен быть какой-то компонент входа, который служит скелетом, не так ли? - person Max Yakovenko; 16.10.2016
comment
Еще одна вещь, теперь у меня есть эта проблема: Uncaught (в обещании): SyntaxError: Не удалось выполнить «добавить» в «DOMTokenList»: предоставленный токен не должен быть пустым. Что бы это могло быть? - person Max Yakovenko; 16.10.2016
comment
app.vendor.js передает его в строке 2723. Я не могу разместить его здесь, поэтому добавлю описание stacktrace к вопросу. - person Max Yakovenko; 16.10.2016