I have created a mat-dialog component to fire for http response. When I include a ngIf statement inside the html for the mat-dialog,it is not handled. On the console it shows a warning as follows.
Can't bind to 'ngIf' since it isn't a known property of 'div'.
NgIf works fine in all other components in the project.
Calling for mat-dialog inside typescript file.
this.matDialog.open(PaymentModelComponent, {
width: "630px",
data: { message: response.comment },
autoFocus: false,
height: "630px",
});
html code
<div *ngIf="true"><p>Show this only if "show" is true</p></div>
Why do ng-if don't work inside a mat-dialog ?
All I needed to do was to add the DialogComponent to the module's declarations:
declarations: [..., MyDialogComponent]
No need to have the component code in the same file.
All you need to do is add the dialogs to your module imports & declarations. In the same module where the component your dialogs are declared in is declared.
I am posting this hoping that someone may find it useful. This is not the exact answer for this problem, but this is how I overcome my scenario. In my case I was using mat-dialog component as an entry component inside the app.module.ts
entryComponents: [ErrorComponent, UserAccountInfoReloadPopupDialogComponent],
For some reason, ng-if it is not working inside the dialog. It is not only for ng-if, all others like ng-for were not available.
I fixed the issue by defining both components in the same ts file.
#Component({
selector: "app-account-info",
templateUrl: "./account-info.component.html",
styleUrls: ["./account-info.component.css"],
})
export class AccountInfoComponent implements OnInit {
//code
}
#Component({
selector: "user-account-info-reload-popup-dialog",
templateUrl: "./payment-modal.component.html",
styleUrls: ["./payment-modal.component.css"],
})
export class UserAccountInfoReloadPopupDialogComponent implements OnInit {
//code
}
Then I defined the newly created mat-dialog component inside angular module declaration.
#NgModule({
declarations:
[
UserAccountInfoReloadPopupDialogComponent
],
This fixed my issue. You can check the angular mat-dialog documentation.
https://material.angular.io/components/dialog/overview
Related
I am running UI Router with angular 4.x. Below code is not rendering anything and I did not get any error message too. But when I changed to $default as a view name, then I am getting the page.Please suggest me.
<app-root>
<ui-view name='main'></ui-view>
</app-root>
Below is the angular State Definition,
export const appState = {
name: 'app',
views : {
main : {
component: AppComponent
}
}
};
When Angular application bootstrap's, it wipes out the inner content of app-root(root) component. What ever you put inside root component will appear until Angular application bootstrap. Generally this place has been used to add Splash screen, loader to show initial loading.
To see your ui-view to replace via ui-router configuration, you should add ui-view inside app-root component HTML.
#Component({
selector: 'app-root',
template: `<ui-view name='main'></ui-view>`
})
export AppRootComponent {
}
We're in the process of getting Angular up and running in our AngularJS app, but I'm facing an issue with mixing upgraded and downgraded components.
Here's the structure of my current problem
The outermost layer is our main application.
The next layer is my new Angular component, which is downgraded, so that I can use it in the AngularJS part of my app. (It's loaded in a ui-router state).
The last layer is an AngularJS component, that has been upgraded to be used in the Angular component.
The last layer is what triggers the issue. When upgrading (following the docs on angular.io), it starts throwing this error:
No provider for ElementRef!
Here are some snippets that might provide the info needed to help out
AngularJS component:
export const ProductComponent: ng.IComponentOptions = {
template: require('./product.html'),
controller: ProductController,
bindings: {
channel: '<',
datastandardId: '<',
productFamily: '<'
}
};
...
someModule.component('lpProduct', ProductComponent);
Upgraded to Angular:
#Directive({
selector: 'lp-product-ng2'
})
export class ProductDirective extends UpgradeComponent implements OnInit {
#Input() productFamily;
#Input() channel;
#Input() datastandardId;
constructor(#Inject('ElementRef') elementRef: ElementRef, #Inject('Injector') injector: Injector) {
super('lpProduct', elementRef, injector);
}
ngOnInit() {
super.ngOnInit();
}
}
#NgModule({
imports: [
...
],
exports: [...],
declarations: [
...,
ProductDirective
],
entryComponents: [...],
providers: [
...
]
})
export class CategoryListViewModule {
}
AngularJS component used in the Angular component template
<lp-product-ng2
*ngIf="selectedProduct"
[productFamily]="selectedProduct"
[channel]="channel"
[datastandardId]="datastandardId">
</lp-product-ng2>
The *ngIf resolves on (click) of another element, so the exception does not throw until the element is in the DOM. If I remove the *ngIf, the exception is thrown immediately, but originating from another part of the code.
I fear that the issue lies within the nesting of components, but I've got no evidence.
it should be :
#Inject(ElementRef)
and
#Inject(Injector)
Problem:
I am unable to get a function to pass successfully to a downgraded Angular 2 component. I've tried just about every way I can think to pass things in but I am only able to get strings passed in via string interpolation -> some-attribute={{controller.property}}. Here are some of the things I've tried (yes, I know some of them don't make sense...)
some-function="controller.function";
some-function="{{controller.function}}"; //<-- works for data, not functions
[some-function]="{{controller.function}}";
[someFunction]="controller.function";
[(someFunction)]="controller.function";
Setup:
Here is my existing setup which is working for data but not for functions:
Angular 1 usage
<my-component data-input-name="{{controller.name}}"></my-component>
Upgrade/Downgrade adapter
angular.module('myModule').directive('myComponent',
downgradeComponent({
component: MyComponent,
inputs: ['inputName']
}) as angular.IDirectiveFactory);
Angular 2 definition
#Component({
selector: 'my-component',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
#Input() inputName: any;
constructor() {}
}
The Angular docs even show how to set it up but they don't give any examples of actual usage.
Am I missing something or can this just not be done?
Use AngularJS kebab case like this, seems to work for me:
<my-component [data-input-name]="controller.name">
</my-component>
I tried to search but I didn't get the answer.
I can't realize when I must define "providers" section in #Component definition.
I looked over examples.
half of them use
1)
import { Component, blah-blah} from '#angular/core';
import { SomeService } from './some.service';
#Component({
selector: 'example-selector',
providers: [SomeService ],
.....
constructor(public someService : SomeService ,
2) but half of them WITHOUT "providers" section!
import { Component, blah-blah} from '#angular/core';
import { SomeService } from './some.service';
#Component({
selector: 'example-selector',
.....
constructor(public someService : SomeService ,
===
so, I am confused: when I need that section and when I don't?
I believe Maxouhell gave the right answer in another question:
If you provide your service inside your component, it will be local to it. So if you have two instance of your component, you will have two instance of your service.
Now if you provide your service inside your module, it will be global and if you have two instance of your component, they will share the same instance of the service.
I believe it has to do with at what level you declare your providers. You must declare a provider for each component or service that you use
For example in my app, I have a service that I provide in main.ts which is then available to any component without having to indicate the provider there.
bootstrap(AppComponent,
[
APP_ROUTER_PROVIDER,
HTTP_PROVIDERS,
SettingsService,
disableDeprecatedForms(),
provideForms()
]).catch((err: any) => console.error(err));
#Component({
selector: 'kg-Settings ',
templateUrl: './app/components/settings/settings.component.html',
styleUrls: ['./app/components/settings/settings.component.css'],
directives: [ROUTER_DIRECTIVES, REACTIVE_FORM_DIRECTIVES]
})
However, if I want to inject a component into another component and it has not been previously provided for at a higher level in the app tree,
#Component({
selector: 'k-Calculator ',
templateUrl: './app/components/calculator/calculator.component.html',
styleUrls: ['./app/components/calculator/calculator.component.css'],
directives: [ROUTER_DIRECTIVES, REACTIVE_FORM_DIRECTIVES, Panel, Dropdown, SelectButton, Button],
providers: [CalculationService]
})
You need provider section whenever you need to use a service in that component.
Item #1, defined the provider within the component.
Item #2, (might) defined the provider in app.component.ts (Please check the main file)
I used to build applicaitons with angular1, there was possible to have directives on the allready loaded DOM elements, it was like you have the main component (app), wich is build from loaded html and then inside you can load directives from ether loaded html or load it from URL.
Howewer in angular2 it seems that to bootsrap application I have to use component which requires me to have template/templateURL, which I think is not nessesery since I don't want to load seperatly menues and other common stuff, I would rather do that on server level then laoding it seperatly. Does anyone knows how could I achive this in angular2?
In Angular2 you need to bootstrap a component and a component needs to have a view. Directives can't be bootstrapped. Directives can't be added or removed dynamically, they are only applied where static HTML in a components view matches their selector.
To me it sounds that for your use case Angular1 is the better fit.
You can have directives but as #Günter Zöchbauer mentioned before you will need to bootstrap a component..
Change detector are created when a component is first instantiated. Here is an exaple for ng2 Directive from Angular documentation :
class Greeter {
greet(name:string) {
return 'Hello ' + name + '!';
}
}
#Directive({
selector: 'needs-greeter'
})
class NeedsGreeter {
greeter:Greeter;
constructor(greeter:Greeter) {
this.greeter = greeter;
}
}
#Component({
selector: 'greet',
viewProviders: [
Greeter
],
template: `<needs-greeter></needs-greeter>`,
directives: [NeedsGreeter]
})
class HelloWorld {
}
See for more details: https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html#!#constructor
But keep in mind that:
Each Angular component requires a single #Component annotation. The
#Component annotation specifies when a component is instantiated, and
which properties and hostListeners it binds to.
When a component is instantiated, Angular
creates a shadow DOM for the component.
loads the selected template into the shadow DOM.
creates all the injectable objects configured with providers and viewProviders.