as i am new to angular2 i am expecting to find out a solution for the following scenario.
The jQuery plugin is not working after getting the data -http://www.owlcarousel.owlgraphic.com/
i got issues on *var owl = jQuery(this.elementRef.nativeElement).find('#breif');
owl.owlCarousel();
My full code are given bellow
angular 2 component:
/ beautify ignore:start /
import {Component, OnInit , ElementRef, Inject } from '#angular/core';
import {FORM_DIRECTIVES} from '#angular/common';
import {CAROUSEL_DIRECTIVES} from 'ng2-bootstrap/components/carousel';
/ beautify ignore:end /
import {Api} from '../../../../services/api';
declare var jQuery:any;
#Component({
selector: 'breif',
directives: [CAROUSEL_DIRECTIVES],
template: require('./template.html')
})
export class BreifComponent implements OnInit {
elementRef: ElementRef;
breifs: Object;
public myInterval:number = 5000;
public noWrapSlides:boolean = false;
public slides:Array<any> = [];
constructor(#Inject(ElementRef) elementRef: ElementRef , private api: Api) {
this.elementRef = elementRef
this.loadBreif();
}
ngOnInit() {
**var owl = jQuery(this.elementRef.nativeElement).find('#breif');
owl.owlCarousel();**
}
loadBreif(){
this.api.getBreif().subscribe(
data => {
this.breifs = data.result.articles;
},
err => console.error(err),
() => {
}
)
}
}
template.html
<div class="owl-carousel" id="breif" >
<div class="item" *ngFor="let breif of breifs"><h4>{{breif.title}}</h4></div>
Hi I posted a workaround of using owl owl.carousel#2.1.4 with angular 2.0.0 + webpack + jQuery#3.1.0.
Some of the issues I faced was with the jQuery plugin.
Please be more specific about the exception/error...
First U'll need to install the above^ packages via npm or similar.
Then --> npm install imports-loader
(for using owl within component otherwise u'll get fn is undefined...since third-party modules are relying on global variables like $ or this being the window object...).
In case you are using WebPack:
imports-loader as follow:
{test: /bootstrap\/dist\/js\/umd\//, loader: 'imports?jQuery=jquery'}
Also u can use jQuery with webpack:
var ProvidePlugin = require('webpack/lib/ProvidePlugin');
In the plugin section of webpack.common.js:
plugins: [
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery'
})
]
For images loader:
{
test: /\.(png|jpe?g|gif|ico)$/,
loader: 'file?name=public/img/[name].[hash].[ext]'
}
*public/img -- images folder
CSS loader:
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw'
}
The vendors.js file should import the following:
import 'jquery';
import 'owl.carousel';
import 'owl.carousel/dist/assets/owl.carousel.min.css';
Please be aware that owl.carousel 2 is still use andSelf() deprecated function of jQuery so we need to replace them with the new version of addBack().
Goto node_modules folder in the owl package dist/owl.carousel.js:
replace all the occurrences of andSelf() with --> addBack().
Now is the angular 2 part:
owl-carousel.ts:
import {Component} from '#angular/core';
#Component({
selector: 'carousel',
templateUrl: 'carousel.component.html',
styleUrls: ['carousel.css']
})
export class Carousel {
images: Array<string> = new Array(10);
baseUrl: string = './../../../../public/img/650x350/';
}
carousel.component.ts:
import { Component, Input, ElementRef, AfterViewInit, OnDestroy } from '#angular/core';
#Component({
selector: 'owl-carousel',
template: `<ng-content></ng-content>`
})
export class OwlCarousel implements OnDestroy, AfterViewInit{
#Input() options: Object;
$owlElement: any;
defaultOptions: Object = {};
constructor(private el: ElementRef) {}
ngAfterViewInit() {
for (var key in this.options) {
this.defaultOptions[key] = this.options[key];
}
var temp :any;
temp = $(this.el.nativeElement);
this.$owlElement = temp.owlCarousel(this.defaultOptions);
}
ngOnDestroy() {
this.$owlElement.data('owlCarousel').destroy();
this.$owlElement = null;
}
}
carousel.component.html:
<owl-carousel class="owl-carousel"[options]="{navigation: true, pagination: true, rewindNav : true, items:2, autoplayHoverPause: true, URLhashListener:true}">
<div class="owl-stage" *ngFor="let img of images; let i=index">
<div class="owl-item">
<img src="{{baseUrl}}{{i+1}}.png"/>
</div>
</div>
</owl-carousel>
Make sure to bootstrap everything in the app.module:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import {OwlCarousel} from './components/carousel/carousel.component';
import {Carousel} from './components/carousel/owl-carousel';
#NgModule({
imports: [
BrowserModule,
NgbModule,
],
declarations: [
AppComponent,
OwlCarousel,
Carousel
],
providers: [appRoutingProviders],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Related
i want to use Ckeditor and Ckfinder thgother in angular .
i u use by this way :
Module :
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { BrowserModule } from '#angular/platform-browser';
import { CKEditorModule } from '#ckeditor/ckeditor5-angular';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
CKEditorModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
and this is my component :
import { Component, OnInit } from '#angular/core';
import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic';
import CKFinder from '#ckeditor/ckeditor5-ckfinder/src/ckfinder';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
public Editor = ClassicEditor;
ngOnInit(): void {
ClassicEditor
.create(document.querySelector('#editor'), {
plugins: [CKFinder],
// Enable the "Insert image" button in the toolbar.
toolbar: ['uploadImage' ],
ckfinder: {
// Upload the images to the server using the CKFinder QuickUpload command.
uploadUrl: 'https://example.com/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images&responseType=json'
}
});
}
}
and this is Html Code :
<ckeditor [editor]="Editor" [config]="{ toolbar: [ 'heading','ckfinder', '|', 'bold', 'italic' ] }"
data="<p>Hello, world!</p>"></ckeditor>
but it show me this error:
Uncaught CKEditorError: ckeditor-duplicated-modules
whats the problem ? how can i use the Ckfinder in angular ?
You can use the official CK Editor 5 Angular component.
Documentation: https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/angular.html
GitHub:
https://github.com/ckeditor/ckeditor5-angular
You can create a custom build using Online Builder tool with all the required plugins and then import that build in angular.
I have been using the custom build with custom plugins without any issues.
I need to load components dynamically to view on some button click.
I have created on directive and some components in my custom module.
But when I try to create new instance of component it says No component factory found.
Here is my code structure.
dashboard module
#NgModule({
declarations: [MainPageComponent, WidgetComponent, ChartsComponent, GraphsComponent, InfographicsComponent, InsertionDirective],
imports: [
CommonModule,
GridsterModule,
ButtonsModule,
ChartsModule,
DropDownsModule
],
entryComponents: [MainPageComponent, WidgetComponent, ChartsComponent, GraphsComponent, InfographicsComponent],
exports: [MainPageComponent, WidgetComponent, ChartsComponent, GraphsComponent, InfographicsComponent]
})
export class DashboardModule {
static customization(config: any): ModuleWithProviders {
return {
ngModule: DashboardModule,
providers: [
{ provide: Service, useClass: config.service }
]
}
}
}
dashboard/insert directive
import { Directive, ViewContainerRef } from '#angular/core';
#Directive({
selector: '[appInsertion]'
})
export class InsertionDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
1. dashboard/mainMainPageComponent.ts
import { Component, OnInit, ViewChild, ComponentFactoryResolver, ComponentRef, Type } from '#angular/core';
import { Service } from 'src/app/services/service';
import { Widget } from 'src/app/interface/widget';
import { GridsterConfig, GridsterItem } from 'angular-gridster2';
import { SETTINGS } from '../settings'
import { InsertionDirective } from '../insertion.directive';
import { ChartComponent } from '#progress/kendo-angular-charts';
#Component({
selector: 'dasbhoard-main-page',
templateUrl: './main-page.component.html',
styleUrls: ['./main-page.component.css']
})
export class MainPageComponent implements OnInit {
componentRef: ComponentRef<any>;
childComponentType: Type<any>;
#ViewChild(InsertionDirective)
insertionPoint: InsertionDirective;
public title: string;
public widgets: Array<{ widget: Widget, grid: GridsterItem, type: string }> = [];
public options: GridsterConfig;
constructor(private service: Service, private componentFactoryResolver: ComponentFactoryResolver) {
this.title = 'Dashboard';
}
ngOnInit() {
this.options = {
itemChangeCallback: MainPageComponent.itemChange,
itemResizeCallback: MainPageComponent.itemResize,
};
}
addNewWidget(type: string) {
let widgetType = SETTINGS.widgetSetting[type];
let totalWidgets = this.widgets ? this.widgets.length : 0;
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(widgetType.useClass);
//widgetType.useClass = ChartsComponent
// when I pass it statically its ok
//error here
let viewContainerRef = this.insertionPoint.viewContainerRef;
viewContainerRef.clear();
this.componentRef = viewContainerRef.createComponent(componentFactory);
this.widgets.push({ widget: { id: totalWidgets, header: `Widget ${totalWidgets} Header`, content: `<h1>Widget ${totalWidgets} Body</h4>` }, grid: { cols: 1, rows: 1, x: 0, y: 0 }, type: type });
}
}
dashboard/main-component/main-component.html
<ng-template appInsertion> </ng-template>
<button kendoButton(click) = "addNewWidget('charts')"[primary] = "true" class="pull-right" > Add Chart Widget </button>
I have each and every posts and all says you need to insert componets into entry points but I've already included all components to entry points. And all components are inside the same module but still it says no No component factory found for ChartsComponent. Did you add it to #NgModule.entryComponents?.
Any one please can you find out the where I'm doing wrong?
Thanks in advance.
I think it's just a typo:
In entryComponents you've written ChartsComponent and in the resolveComponentFactory method you've written ChartComponent
Could that be it?
I followed official angular-cli tutorial to integrate angular-universal to my existing angular-cli app.
I am able to do SSR for my angular-cli app. But when I try to integrate ngx-leaflet, I am getting following error:
ReferenceError: navigator is not defined
at D:\ng2-ssr-pwa\dist\server.js:40251:29
Now, I understand that leaflet is trying to access navigator object which is not available in the Node context. So I decided to delay leaflet rendering until the page is loaded in the browser as given in this SO thread.
But still I am getting same error. You can look the demo app with leaflet issue here.
./src/app/browserModuleLoader.service.ts:
import { Component, Inject, Injectable, OnInit, PLATFORM_ID } from '#angular/core';
import { isPlatformBrowser, isPlatformServer } from '#angular/common';
#Injectable()
export class BrowserModuleLoaderService {
private _L: any;
public constructor(#Inject(PLATFORM_ID) private _platformId: Object) {
this._init();
}
public getL() {
return this._safeGet(() => this._L);
}
private _init() {
if (isPlatformBrowser(this._platformId)) {
this._requireLegacyResources();
}
}
private _requireLegacyResources() {
this._L = require('leaflet');
}
private _safeGet(getCallcack: () => any) {
if (isPlatformServer(this._platformId)) {
throw new Error('invalid access to legacy component on server');
}
return getCallcack();
}
}
./src/app/leaflet/app/leaflet.component.ts:
// import * as L from 'leaflet';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, PLATFORM_ID } from '#angular/core';
import { BrowserModuleLoaderService } from '../browserModuleLoader.service';
import { isPlatformBrowser } from '#angular/common';
#Component({
selector: 'app-leaflet',
styleUrls: ['./leaflet.component.scss'],
template: `
<div *ngIf="isBrowser">
<div leaflet [leafletOptions]="options"></div>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LeafletComponent {
isBrowser: boolean;
options = {};
constructor(private cdr: ChangeDetectorRef,
#Inject(PLATFORM_ID) platformId: Object,
private browserModuleLoaderService: BrowserModuleLoaderService
) {
this.isBrowser = isPlatformBrowser(platformId);
}
ngAfterViewInit() {
console.log('this.isBrowser ', this.isBrowser);
if (this.isBrowser) {
const L = this.browserModuleLoaderService.getL();
this.options = {
layers: [
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' }),
],
zoom: 5,
center: L.latLng({ lat: 38.991709, lng: -76.886109 }),
};
}
this.cdr.detach();
}
}
./src/app/app.component.html:
<div>
<app-leaflet></app-leaflet>
</div>
How do I safely delay the leaflet rendering until the platform is not browser?
EDIT:
I removed all code related to leaflet (browserModuleLoader.service.ts, leaflet.component.ts ect. ) and kept only leaflet module import in app.module.ts and actually this import is causing issue.
./src/app/app.module.ts:
import { AppComponent } from './app.component';
import { BrowserModule } from '#angular/platform-browser';
// import { BrowserModuleLoaderService } from './browserModuleLoader.service';
// import { LeafletComponent } from './leaflet/leaflet.component';
import { LeafletModule } from '#asymmetrik/ngx-leaflet';
import { NgModule } from '#angular/core';
#NgModule({
declarations: [
AppComponent,
// LeafletComponent
],
imports: [
BrowserModule.withServerTransition({appId: 'my-app'}),
LeafletModule.forRoot()
],
providers: [
// BrowserModuleLoaderService
],
bootstrap: [AppComponent]
})
export class AppModule { }
./src/app/app.server.module.ts:
import {AppComponent} from './app.component';
import {AppModule} from './app.module';
import {ModuleMapLoaderModule} from '#nguniversal/module-map-ngfactory-loader';
import {NgModule} from '#angular/core';
import {ServerModule} from '#angular/platform-server';
#NgModule({
imports: [
AppModule,
ServerModule,
ModuleMapLoaderModule
],
bootstrap: [AppComponent],
})
export class AppServerModule {}
How do I handle this nxg-leaflet module import?
Solved this issue by using Mock Browser.
server.ts:
const MockBrowser = require('mock-browser').mocks.MockBrowser;
const mock = new MockBrowser();
global['navigator'] = mock.getNavigator();
Fixed by (global as any).navigator = win.navigator;, much more elegant, definitely native, and without relying on outdated Mock Browser.
I too was receiving this error with Angular Universal. Using the Mock Browser from the solution above did fix this error for me, but it also started a new Warning related to CommonJS. Rather than digging into that issue, I realized I was already using Domino in my server.ts file, so I could easily set the navigator with Domino. This is what worked best for me:
npm install domino
server.ts:
const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs
.readFileSync(path.join('dist/<your-app-name>/browser', 'index.html')) //<--- REPLACE WITH YOUR APP NAME
.toString();
const window = domino.createWindow(template);
global['window'] = window;
global['document'] = window.document;
global['navigator'] = window.navigator;
I am trying to add the components dynamically in angular4.
I checked with other questions, But i cant find solution.
I got the error
ERROR TypeError: Cannot read property 'createComponent' of undefined
on dynamic components.
adv.component.ts
import { Component, OnInit, AfterContentInit, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '#angular/core';
import { SampleComponent } from '../sample/sample.component';
#Component({
selector: 'app-adv',
templateUrl: './adv.component.html',
styleUrls: ['./adv.component.css']
})
export class AdvComponent implements OnInit, AfterContentInit {
#ViewChild('container', {read:'ViewContainerRef'}) container;
constructor(private resolver : ComponentFactoryResolver) { }
ngOnInit() {
}
ngAfterContentInit(){
const sampleFactory = this.resolver.resolveComponentFactory(SampleComponent);
this.container.createComponent(sampleFactory);
}
}
adv.component.html
<div #container></div>
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { AdvComponent } from './adv/adv.component';
import { SampleComponent } from './sample/sample.component';
#NgModule({
declarations: [
AppComponent,
AdvComponent,
SampleComponent
],
entryComponents:[
SampleComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
About ngAfterViewInit in docs:
Respond after Angular initializes the component's views and child
views.
while ngAfterContentInit:
Respond after Angular projects external content into the component's
view.
So the child view is not ready in ngAfterContentInit, so move this part
ngAfterContentInit(){
const sampleFactory = this.resolver.resolveComponentFactory(SampleComponent);
this.container.createComponent(sampleFactory);
}
to
ngAfterViewInit() {
const sampleFactory = this.resolver.resolveComponentFactory(SampleComponent);
this.container.createComponent(sampleFactory);
}
Also change:
#ViewChild('container', {read:'ViewContainerRef'}) container;
to
#ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef
I need to set input, configuration parameters, to a component that is not mentioned in index.html.
I can see how to do that for component selectors that are included in index.html.
How can I do from index.html?
You can have your configuration in your Main module class as below
import {Component, NgModule} from '#angular/core'
import {BrowserModule} from '#angular/platform-browser'
#Component({
selector: 'my-app',
template: `
<div>
<h2>{{name}} Sample</h2>
{{myConfiguration | json}}
</div>
`,
})
export class App {
name:string;
myConfiguration:any=myConfiguration;
constructor() {
console.log(myConfiguration);
this.name = 'Global Configuration'
}
}
#NgModule({
imports: [ BrowserModule ],
declarations: [ App ],
bootstrap: [ App]
})
export class AppModule {
var myConfiguration={id:1,devmode:true};
}
LIVE DEMO