1

Я использую angular2-universal для рендеринга на стороне сервера и создания статического HTML.Селектор «app» не соответствует ни одному элементу

Пока что мой статический 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" 
 
      } 
 
     ] 
 
    } 
 
    ]; 
 
}

ответ

0

После просмотра этого кода я понял, что это развернув приложение на стороне клиента тоже.

После удаление из-за рубежа от client.ts работает нормально.

bootstrap(App,[HTTP_PROVIDERS,]); 

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

, что я понять из этого, приложение попытается загрузить компонент два раза,

с клиентской стороны & стороне сервера соответственно.

Таким образом, он отображал компонент на стороне сервера, но не смог найти селектор для компонента на стороне клиента.

+0

Это целая точка с Angular Universal, чтобы загрузить сайт как на стороне сервера, так и дать быстрое первое впечатление, а затем загрузите клиентскую часть приложения снова, позволяя угловому захвату маршрутизации и управлению приложением. В противном случае все, что у вас есть, это простая статическая веб-страница. – Gerardlamo

Смежные вопросы