我使用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> </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> </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> </td>
<td> </td>
<td> </td>
<td> </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> </td>
<td> </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> </td>
<td> </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"
}
]
}
];
}
&#13;
答案 0 :(得分:0)
看了这段代码后,我意识到它也在客户端引导应用程序。
在从client.ts下面删除以下行之后,它可以正常工作。
bootstrap(App,[HTTP_PROVIDERS,]);
从client.ts中删除此行后,应用程序没有产生任何错误。 但我不确定为什么普遍首发人员在使用服务器端渲染时首先使用了这一行。
我从中理解的是,应用程序尝试加载组件两次,
来自客户端&amp;服务器端。
因此它呈现了服务器端组件,但未能找到客户端组件的选择器。