C0ol_Cod3r
C0ol_Cod3r

Reputation: 949

Angular 2 Second Component Not Working?

Ok, so my app currently has one module, which has two components, one is a gallery, which I bootstrap to start my app. The other is, or will be my menu system, however my A2 app seems to not render/run the component.

Module:

import { NgModule }      from '@angular/core';
import { HttpModule }    from '@angular/http';
import { BrowserModule } from '@angular/platform-browser';
import { MenuComponent } from '../components/menu';
import { GalleryComponent }  from '../components/gallery';

@NgModule({
  imports:      [ BrowserModule, HttpModule ],
  declarations: [ GalleryComponent, MenuComponent ],
  bootstrap:    [ GalleryComponent ]
})

export class AppModule { }

Menu:

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: '[data-menu]',
  template: `<div></div>`
})

export class MenuComponent {
  constructor() {
    console.log('test 99 - const.');
  }
}

So my gallery component is fine, that works without any issues. However the very simple test Menu component I setup to test, does not seem to do anything. If I bootstrap the component, it runs the console.log. So what the hell am I doing wrong?

I have been on the A2.io site and look other again and again some of the test examples they have, but still cant see why this is not working?

Please help.

EDIT

I should have said that this A2 app is running within a Symfony 2, which is what I built the Json API for the gallery with.

So I have a Twig template (apart of Symfony) load the section tag with my data sector for my gallery, like so:

home.html.twig:

<main>
    <div id="PublicGallery">

        <section data-my-app>// Loading //</section> <- this loads my gallery without any issues!

    </div>
</main>

Above this I was going to but my nav tag, but I have not done that let, as I can not get the second A2 component to even console log?

Upvotes: 0

Views: 1702

Answers (2)

dparsons
dparsons

Reputation: 2866

I don't have any experience working with Twig or Symfony (or bootstrapping without SystemJS for that matter) so I can't speak specifically about what you need to do within them to make this work. That being said, a few things do jump out at me.

So my gallery component is fine, that works without any issues. However the very simple test Menu component I setup to test, does not seem to do anything.

I don't see anywhere in the code you have provided where you are actually tying these two components together in a template.

Ok, so my app currently has one module, which has two components, one is a gallery, which I bootstrap to start my app

What is likely happening is that the component you are bootstrapping is not tying in the other component. The snippets below are from an application that I am currently working on that you should be able to adapt to your needs. I have written this at a very basic level since I don't know how familiar you are with Angular2.

file: index.html

<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <base href="/">
    <title>Some App</title>

    <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>

    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
</head>
<body>
    <ngApp></ngApp>
</body>
</html>

Since you aren't using SystemJS you can ignore that bit, but what is really important here are the ngApp tags. Think of these tags as the entry point into the rest of your application. The following component will use these tags as a 'marker' on where to place its output.

file: app.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'ngApp',
    templateUrl: './app.template.html'
})

export class AppComponent {
}

This is really just boilerplate code and not much of interest, but notice that ngApp is the selector for this component. This is the first part in tying your application to your entry point. Next is the template that this component will use.

file: app.template.html

<nav>
    <data-menu></data-menu>
</nav>
<gallery-component></gallery-component>

This is straightforward, but important. The data-menu and gallery-component tags are where the two components you have already written are going to be displayed, but you need to make a modification to each of your components first. In your gallery set the selector to: selector: 'gallery-component' and in your menu set the selector to selector: 'data-menu' Next we need to setup the module.

file: app.module.ts

import { NgModule }      from '@angular/core';
import { HttpModule }    from '@angular/http';
import { BrowserModule } from '@angular/platform-browser';
import { MenuComponent } from '../components/menu';
import { GalleryComponent }  from '../components/gallery';
import { AppComponent }  from '../components/app.component';

@NgModule({
  imports:      [ BrowserModule, HttpModule ],
  declarations: [ AppComponent, GalleryComponent, MenuComponent ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }

Notice here that we include the AppComponent and that it is the component that we are bootstrapping. The last thing is to make sure our main file is in order.

file: main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

If you run the app at this point it should display a browser window with your menu component stacked on top of your gallery.

A few parting thoughts / notes

  • You obviously don't need to use templateUrl and can instead use template if you prefer, but I don't like having templates baked directly into the component code.
  • The much shorter answer to your question is simply that if you modify the template of your menu control to be something like template: <div><gallery></gallery></div> assuming that you bootstrap the menu and the gallery has a selector value of 'gallery' it should display. That isn't really useful though because that tightly couples the menu component to the galley component.
  • Speaking of tight coupling, you will notice that both your menu and gallery components are now tightly coupled to the app component. That is not terribly useful either. Instead app.component should probably be setup with a router-outlet so that different components can be loaded on the page when menu options are clicked. You can read about routing and navigation here

If you have any questions or if I haven't made something clear, please let me know.

Upvotes: 1

lthh89vt
lthh89vt

Reputation: 164

I guess, you will need this in your GalleryComponent Template

<div data-menu></div>

Without looking at your GalleryComponent. I can't really tell what happening here.

Upvotes: 0

Related Questions