2015-10-23 8 views
24

Ich habe zwei verschachtelte @Components de eckigen 2. Die Ansicht rendert nur gut, aber es wirft immer ein Javascript Fehler beim ersten Mal. Hier ist mein Code in Typescript.Angular2 Selector hat keine Elemente in verschachtelten Komponenten

App HTML:

<body> 
    <my-app>loading...</my-app> 
</body> 

App Komponente:

import {bootstrap, Component} from 'angular2/angular2'; 
import {CanvasComponent} from "./CanvasComponent"; 

@Component({ 
    selector: 'my-app', 
    template: ` 
     <h1>{{title}}</h1> 
     <h2>My Games</h2> 
     <div> 
     <my-canvas></my-canvas> 
     </div> 
    `, 
    directives: [CanvasComponent] 
}) 

class AppComponent { 
} 

bootstrap(AppComponent); 

Leinwand Komponente:

import {bootstrap, Component, View} from 'angular2/angular2'; 

@Component({ 
    selector: 'my-canvas' 
}) 

@View({ 
    template: ` 
    <div> 
    <span>Balls:</span> 
    <div>{{canvas.length}}</div> 
    </div> 
    ` 
}) 

export class CanvasComponent { 
    canvas = [1,2,3]; 
} 

bootstrap(CanvasComponent); 

Der Fehler ist:

EXCEPTION: The selector "my-canvas" did not match any elements 

Antwort

44

Entfernen Sie bootstrap(CanvasComponent) aus Ihrer CanvasComponent Datei. Es versucht, die Anwendung zum zweiten Mal zu starten, indem Sie CanvasComponent als root verwenden und nach my-canvas Element in Ihrem App HTML suchen. Natürlich kann es es nicht finden.

+0

Okay, sagen wir mal, 'CanvasComponent' benötigt' HTTP_PROVIDERS' und andere Dienste. Wie würdest du es injizieren? Ich denke, die Root-Komponente sollte sich darum kümmern, diese Dienste zu injizieren. – Pablo

+0

@Pablo, fügen Sie es einfach dem Bootstrap-Aufruf für Ihre App 'bootstrap (AppComponent, [HTTP_PROVIDERS]) hinzu;' Fügen Sie dann CanvasComponent einen Konstruktor hinzu, den Sie mit '@ Inject' annotieren müssen, zB:' constructor (@Inject (Http) öffentliche http: Http) {} ' – svallory

+0

@svallory danke, ich habe DI erreicht, indem ich die' providers'-Eigenschaft innerhalb der @Component verwendet habe. Siehe https://github.com/ghpabs/angular2-seed-project/blob/master/src/scripts/todo/todocomponent.ts#L12-L17. Auf diese Weise finde ich die Komponente besser eingekapselt. Gedanken? – Pablo

14

Ich behob das Problem durch Ändern des Namens in der index.html, sollten Sie sicher sein, dass das Tag in der index.html der selbe Selektor in der Hauptkomponente sind.

<html> 
     <head> 
     <title>Angular 2 QuickStart</title> 
     <meta charset="UTF-8"> 
     <meta name="viewport" content="width=device-width, initial-scale=1"> 
     <link rel="stylesheet" href="stylesheets/styles.css"> 
     <!-- 1. Load libraries --> 
     <!-- Polyfill(s) for older browsers --> 
     <script src="node_modules/core-js/client/shim.min.js"></script> 
     <script src="node_modules/zone.js/dist/zone.js"></script> 
     <script src="node_modules/reflect-metadata/Reflect.js"></script> 
     <script src="node_modules/systemjs/dist/system.src.js"></script> 
     <!-- 2. Configure SystemJS --> 
     <script src="systemjs.config.js"></script> 
     <script> 
     System.import('app').catch(function(err){ console.error(err); }); 
     </script> 
     </head> 
     <!-- 3. Display the application --> 

     <body> 
     <my-app>Loading...</my-app> <!-- THIS TAG SHOULD BE THE SAME THAT THE SELECTOR IN THE MAIN COMPONENT --> 
     </body> 
    </html> 

<!-- end snippet --> 

    </body> 
</html>