Angular2 ngFor not working - javascript

I am trying to implement a basic shopping list, but my ngFor in Angular is not working.
import { Component, View } from 'angular2/angular2';
#Component({
selector: 'my-app'
})
#View({
template: '<h1>{{title}}</h1><ul><li *ngFor="let i of items"><span>{{i}}</span></li></ul>'
})
export default class MyAppComponent {
title = 'ShoppinList';
items = ['Milk','Ham','Eggs'];
}
The only thing that appears is "loading..." and I am getting more than 10 cryptic errors.

Without trying it first I noticed an error in the import statement at the top. Should be:
import { Component } from '#angular/core'

#View() was removed almost a year ago. If you see examples that use it, just move the content to the #Component() decorator while directives and pipes were moved from #Component() to #NgModule()s declaration.
You need to add CommonModule to #NgModule({ imports: [CommonModule], ...}) export class SomeModule{} in every module where you want to use ngFor (or other directives shippled with Angular - BrowserModule already includes CommonModule).

its good way to use ngIf and use your template inside your component properties.
import { Component, View } from 'angular2/angular2';
#Component({
selector: 'my-app',
template : '<div>
<h1>{{title}}</h1>
<ul *ngIf="items">
<li *ngFor="let i of items"><span>{{i}}</span></li>
</ul>
</div>'
})
export default class MyAppComponent {
title : string = 'ShoppinList';
items : Array<string> = ['Milk','Ham','Eggs'];
}

You don't have to use #View here.
#Component({
selector: 'my-app',
template: `
<div>
{{title}}
<ul><li *ngFor="let i of items"><span>{{i}}</span></li></ul>
</div>
`,
})
export class App {
title = 'ShoppinList';
items = ['Milk','Ham','Eggs'];
}
Working plunker

Related

Angular Drag and Drop component

I try use this component in angular 4
https://github.com/jellyjs/angular2-file-drop
I have something like this
import { Component, OnInit } from '#angular/core';
import { FileDropDirective } from 'angular2-file-drop';
#Component({
selector: 'app-drag-and-drop',
template: `
<div fileDrop
[ngClass]="{'file-is-over': fileIsOver}"
[options]="options"
(fileOver)="fileOver($event)"
(onFileDrop)="onFileDrop($event)">
Drop file here
</div>
`,
directives: [ FileDropDirective ],
styleUrls: ['./drag-and-drop.component.scss']
})
export class DragAndDropComponent implements OnInit {
}
I have error that import FileDropDirective from path has no exported member 'FileDropDirective' and also error in line directives: [ FileDropDirective ],
that Object literal may only specify known properties, and 'directives' does not exist in type 'Component'.
I change
import { FileDropDirective } from 'angular2-file-drop;
to
import { FileDropModule } from 'angular2-file-drop;
and also
directives to providers and working fine

Include variable containing html in a template - angular2

For the purposes of an application written in Angular 2, i need to include dynamics html contained in a variable, to a template. You can see the code here:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: '{{name}}',
})
export class AppComponent { name = '<h2>Angular</h2>'; }
However, the result is not what i want :
<h2>Angular</h2>
I would like to know if there is a technique to include this variable for handle the tags as html.
Ps: i try this code :
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: ' <div innerHTML="name" ></div>',
})
export class AppComponent { name = '<h2>Angular</h2>'; }
But it's not really what i want because i don't want that a div(or another tag) encapsulate the <h2>.
If you don't want to encapsulate the h2, you juste have to write:
<h2 [innerHTML]="name"></h2>
crdly.
PS: name is a variable, if you want to test it with a string try that:
<h2 [innerHTML]="'<b>my html code</b>'"></h2>

Semantic UI with Angular2 - How to set Sidebar settings from jQuery in a component?

I have an Angular2 application and I want to use Semantic UI. However, there are some jQuery configurations like below that I have to run after a component loaded:
$('#app .ui.sidebar')
.sidebar({context:$('#app')})
.sidebar('setting', 'transition', 'overlay')
It is not working by importing the js file in the head of index.html or writing it in a <script> tag inside of a component template. Is there a "typescript way" to do that or how can I use a js file inside of a component?
I found this link about using jQuery in directives, then I created a sidebar directive:
import {Directive, ElementRef, OnDestroy, OnInit, Input} from '#angular/core';
import {HostListener} from "#angular/core/src/metadata/directives";
declare var $: any
#Directive({
selector: '.ui.sidebar'
})
export class SidebarDirective implements OnInit, OnDestroy {
#Input() context: string;
constructor(private el: ElementRef) {
}
public ngOnInit() {
$(this.el.nativeElement)
.sidebar({context: this.context})
.sidebar('setting', 'transition', 'overlay');
}
public ngOnDestroy() {
}
}
Then, I used it in the template:
<div id="app">
<div context="#app" class="ui left vertical menu sidebar"></div>
<div class="pusher"></div>
</div>
I have spent quite some time to get this working although it is rather simple in the end. Hope to save you some time ...
There is no need to create a directive, you can use the jQuery command as you would use with JavaScript (described at https://semantic-ui.com/modules/sidebar.html#/usage). However, "$" has to be declared and the command has to be located in a TypeScript function ("toggle()"):
import {Component} from '#angular/core';
declare var $: any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
toggle() {
$('.ui.sidebar').sidebar('toggle');
}
}
The corresponding section of the template may look like this:
<div class="ui fixed inverted main menu">
<a (click)="toggle()" class="launch icon item">
<i class="content icon"></i>
<p style="padding-left:1em">Menu</p>
</a>
</div>
Don't forget to add jQuery to the scripts section of .angular-cli.json:
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/semantic-ui-css/semantic.min.js"
],
I'm using Semantic UI 2.2.12 which already depends on jQuery 3.2.1. Angular version is 4.4.4 running on node.js 6.11.2.
import { Component, OnInit } from '#angular/core';
declare var $:any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app works!';
ngOnInit(){
$('#app .ui.sidebar')
.sidebar({context:$('#app')})
.sidebar('setting', 'transition', 'overlay') ;
}
}

Angular 2 (Ionic 2): can't "render" Component inside Page

I built an Angular 2 Component:
import {Component, View} from 'angular2/core';
#Component({
selector: 'sidemenu'
})
#View({
templateUrl: 'build/pages/menu/menu.html',
})
export class Menu {
}
in a Page component, I can't use it in the template:
import {Menu} from '../menu/menu';
#Page({
templateUrl: 'build/pages/content/content.html'
})
export class PO {
}
content.html:
<ion-content>
<sidemenu></sidemenu>
</ion-content>
isn't replaced by the Menu component's "html" (build/pages/menu/menu.html). But if I use dynamicComponentLoader to load the component inside an element from the DOM, it works (I did this to check if the component is ok).
Am I missing something?
directives: [Menu]
import {Menu} from '../menu/menu';
#Page({
templateUrl: 'build/pages/content/content.html',
directives: [Menu]
})
export class PO {
}
I don't know Ionic but usually in Angular2 you need to list components you use in the template in the #Component({ ..., directives: [Menu], ...}){ ...}

Angular 2 component without a view

Is it possible to use Angular 2 without using a template or an #View?
I'm looking for a similar way like you did the following in example:
Angular 1
index.html
<div ng-controller="appcontroller">
<div ng-class="{active: isActive()}">
.....
</div>
</div>
app.js
angular.module('app', []).controller('appcontroller', function(){
$scope.isActive = function(){
return true;
}
});
I was guessing it would look something like this, if it was possible:
Angular 2
index.html
<app>
<div [ngclass]="{active: isActive()}">
.....
</div>
</app>
app.ts
import {Component} from 'angular2/core';
#Component({
selector: 'app'
})
export class AppComponent {
isActive(){
return true;
}
}
But unfortunately I'm getting the error:
... must have either 'template', 'templateUrl', or '#View' set.
I don't really like putting html in Javascript, so I hope there some sort of workaround or way to do this.
In fact, you should implement the AppComponent like this:
import {Component} from 'angular2/core';
#Component({
selector: 'app'
template: `
<div [ngClass]="{active: isActive()}">
.....
</div>
`
})
export class AppComponent {
isActive(){
return true;
}
}
or using the templateUrl property:
import {Component} from 'angular2/core';
#Component({
selector: 'app'
templateUrl: 'component.html'
})
export class AppComponent {
isActive(){
return true;
}
}
and use the component like this:
<app></app>
If you put some HTML inside the app tag, this means that you want to provide some content to the component that can be included in the component template using ng-content. Here is a sample: Angular 2 Template Component.
Hope it helps you,
Thierry

Categories

Resources