1

我正在使用 angular2-universal 进行服务器端渲染和生成静态 HTML。

到目前为止,我的静态 HTML 已生成,并且组件也正在渲染。但在我的浏览器控制台中显示此错误。

EXCEPTION: The selector "app" did not match any elements

为此,我使用了以下代码:

1.index.html

<!doctype html>
<html lang="en">

<head>
    <link rel="icon" href="data:;base64,iVBORw0KGgo=">
    <link href="\node_modules\bootstrap\dist\css\bootstrap.min.css" rel="stylesheet" />
    <link href="\node_modules\bootstrap\dist\css\style.css" rel="stylesheet" />
    <script src="/node_modules/es6-shim/es6-shim.js"></script>
    <script src="/node_modules/es6-promise/dist/es6-promise.js"></script>
    <script src="/node_modules/reflect-metadata/Reflect.js"></script>
    <script src="/node_modules/zone.js/dist/zone-microtask.js"></script>
    <script src="/node_modules/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="/dist/client/bundle.js"></script>    
</head>
<body>
    <app>Loading....</app>    
</body>
</html>

2.client.ts

import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS} from 'angular2/http';
import 'rxjs/add/operator/map';
import {App} from './app/app.component';

bootstrap(App,[HTTP_PROVIDERS,]);

3.server.ts

import * as path from 'path';
import * as express from 'express';
import * as universal from 'angular2-universal-preview';

// Angular 2
import {App} from './app/app.component';


let app = express();
let root = path.join(path.resolve(__dirname, '../'));

// Express View
app.engine('.ng2.html', universal.ng2engine);
app.set('views', __dirname);
app.set('view engine', 'ng2.html');

// Serve static files
app.use(express.static(root));
var i = 0;
// Routes
app.use('/', (req, res) => {
    res.render('index_new', {App}, function(err,html){
    console.log("------------------My HTML ---------\n"+(i++));
    console.log(html);
    console.log("------------------My HTML ----------");
    res.send(html);
   });
});

// Server
app.listen(3000, () => {
  console.log('Listen on http://localhost:3000');
});

4.app.component.ts

import {Component} from 'angular2/core';
import {NgSwitch, NgSwitchWhen, NgSwitchDefault,NgFor} from 'angular2/common';
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Rx';

@Component({
    selector: 'app', 
    template: `
            <div *ngFor="#comp of record">
            <div class="col-sm-4 divDynamic">
                <table style="width:100%;">
                    <tr style="background-color:#B8B8B8">
                        <th>{{comp.data[comp.mappings[0].mapAttr]}}</th>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                    </tr>
                </table>
                <br/>
            </div>
            <div class="col-sm-4 divDynamic">
                <table  style="width:100%;">
                    <tr style="background-color:#B8B8B8">
                        <th>{{comp.data[comp.mappings[1].mapAttr]}}</th>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                    </tr>
                </table>
                <br/>
            </div>        
            <div class="col-sm-4 spec" style="float:right;">        
                <table  style="width:100%;">
                    <tr style="background-color:#f5821f;color:white;">
                        <th>{{comp.data[comp.mappings[2].mapAttr]}}</th>
                    </tr>
                    <tr>
                        <td style="border:none;text-align:left;">{{comp.data[comp.mappings[16].mapAttr]}}</td>
                    </tr>
                    <tr>
                        <td style="border:none;text-align:left;">{{comp.data[comp.mappings[15].mapAttr]}}</td>
                    </tr>
                    <tr>
                        <td style="border:none;text-align:left;">{{comp.data[comp.mappings[17].mapAttr]}}</td>
                    </tr>
                </table>
                <br/>
            </div>
            <div class="col-sm-8 spec">       
                <table style="width:100%;">
                    <tr>
                        <td rowspan="2" style="background-color:#f5821f;color:white;" class="col-xs-2 ">{{comp.data[comp.mappings[3].mapAttr]}}</td>
                        <th>{{comp.data[comp.mappings[7].mapAttr]}}</th>
                        <th>{{comp.data[comp.mappings[7].mapAttr]}}</th>
                        <th>{{comp.data[comp.mappings[7].mapAttr]}}</th>
                        <th>{{comp.data[comp.mappings[7].mapAttr]}}</th>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                </table>
                <br/>
            </div>
            <div class="col-sm-8 divDynamic">
                <table style="width:100%;">
                    <tr>
                        <td rowspan="2" style="background-color:#B8B8B8;" class="col-xs-2 ">{{comp.data[comp.mappings[4].mapAttr]}}</td>
                        <th>{{comp.data[comp.mappings[11].mapAttr]}}</th>
                        <th>{{comp.data[comp.mappings[12].mapAttr]}}</th>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                </table>
                <br/>
            </div>
            <div class="col-sm-12 divDynamic">
                <table style="width:100%;">
                    <tr>
                        <td rowspan="2" style="background-color:#B8B8B8;" class="col-xs-2 ">{{comp.data[comp.mappings[5].mapAttr]}}</td>
                        <th>{{comp.data[comp.mappings[13].mapAttr]}}</th>
                        <th>{{comp.data[comp.mappings[14].mapAttr]}}</th>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                </table>
                <br/>
            </div>
            <div class="col-sm-12" style="color:#a41c2b;border:solid #a41c2b 2px;">
                {{comp.data[comp.mappings[6].mapAttr]}}        
            </div>
        </div>   
        `
 })
export class App{
    public record = [{
        "styling": {
            "overall": {}
        },
        "data": {
            "statementDate": "Statement Date",
            "minAmtDue": "Minimum Amount Due",
            "totalAmtDue": "Your Total Amount Due",
            "stmtSummary": "Statement Summary",
            "creditSummary": "Credit Summary",
            "rewards": "REWARDS",
            "bottomPara": "Convert your Big shopping bills into small, manageable EMI's! If any of the below transaction is highlighted,you may login to Internet Banking and convert into EMI now ! TnC apply.",
            "prevBalance": "Previous Balance",
            "purchases": "Purchases/ Charges",
            "cashAdv": "Cash Advances",
            "payments": "Payments/ Credits",
            "creditLimit": "Credit Limit",
            "creditAvail": "Available Credit",
            "pointsEarned": "Points Earned",
            "payback": "Points Transferred to PAYBACK(Acc:",
            "dueDate": "Due Date:",
            "Amt": "Rs.",
            "interest": "Interest will be levied if Total Amount Due is not paid"
        },
        "mappings": [
            {
                "mapAttr": "statementDate"
            },
            {
                "mapAttr": "minAmtDue"
            },
            {
                "mapAttr": "totalAmtDue"
            },
            {
                "mapAttr": "stmtSummary"
            },
            {
                "mapAttr": "creditSummary"
            },
            {
                "mapAttr": "rewards"
            },
            {
                "mapAttr": "bottomPara"
            },
            {
                "mapAttr": "prevBalance"
            },
            {
                "mapAttr": "purchases"
            },
            {
                "mapAttr": "cashAdv"
            },
            {
                "mapAttr": "payments"
            },
            {
                "mapAttr": "creditLimit"
            },
            {
                "mapAttr": "creditAvail"
            },
            {
                "mapAttr": "pointsEarned"
            },
            {
                "mapAttr": "payback"
            },
            {
                "mapAttr": "dueDate"
            },
            {
                "mapAttr": "Amt"
            },
            {
                "mapAttr": "interest"
            }
        ]
    }
    ];
}

4

1 回答 1

0

查看这段代码后,我意识到它也在客户端引导应用程序。

从client.ts删除以下行后,它工作正常。

bootstrap(App,[HTTP_PROVIDERS,]);

从 client.ts 中删除此行后,应用程序没有产生任何错误。但我不确定为什么通用入门者在使用服务器端渲染时首先使用这条线。

我从中了解到的是,应用程序尝试加载组件两次

分别来自客户端和服务器端。

所以它渲染了服务器端组件,但找不到客户端组件的选择器。

于 2016-02-26T10:50:09.803 回答