Angular 2 component dynamic name - angularjs

How i can set dynamic name to angular 2 component?
I have next code in my template:
<{{component} [data]="data" [anotherData]="anotherData"></{{component}}>
And I want do define componentName in my class
component: string = 'component';
Because now i have next error:
Uncaught (in promise): Template parse errors:
Unexpected closing tag "{{component}" ("

<div [ngSwitch]="contactService.contact.cat">
<div *ngSwitchWhen="'person'">
<persons-edit [primary]="true"></persons-edit>
</div>
<div *ngSwitchWhen="'business'">
<businesses-edit [primary]="true"></businesses-edit>
</div>
<div *ngSwitchWhen="'place'">
<places-edit [primary]="true"></places-edit>
</div>
</div>
This is what I use in my app. I have the three components defined, and use a switch to show the one I want. I get the selection here from a service, but you could get it from your root component. Something like this:
#Component {
selector: 'dynamic-component',
....
}
export class DynamicComponent{
#Input selectedcomponent : string;
}
Then use it in a template:
<dynamic-component [selectedcomponent]="person"></dynamic-component>
And instead of using a service, switch on "selectedcomponent".

The Answer is simply You Can't !!
While defining your component you must have to declare name of that component(i.e selector property) as well as class name. without declaring component name you can't create component.
so in your case there are option is either you create no. of components and call whenever you need of that component or create dynamic input value of that component so as per need set your dynamic value and get usng #Input. because for each component there is diff. template and logic as well, so better is to create new components and use as per need.
yes no doubt you can set dynamically data to that component like ID's ,name, custom input etc etc.
hope it clears everything if not comment here !

You cannot dynamically assign names to components the way you try to do it.
However, you can dynamically assign ids to your elements with [attr.id]="id_string_expression"
Most likely you can solve your problem that way.
Something like:
<my-component [attr.id]="name+number" [data]="data" [anotherData]="anotherData"></my-component>

Related

how to use same component in multiple place with some logic in angularjs

Well I have a directive/component/controller i.e <app-form></app-form> I am using this html page into multiple place but I want to to remove some specific field from different in place component how can I do in angularjs
In reactjs we can do like this <app-form disableField></app-form> and if disabledField then disable particular field other wise nothing to do
Again for better understanding for example we have one form having name, email and dob same form is using multiple place but at one place we are not interesting to display dob how can we disable or remove from specific place ?
please guide
You have to use bindings in your component declaration. something on the lines of:
angular.module('app').component('appForm', {
controller: 'AppFormCtrl',
templateUrl: 'app-form.html',
bindings: {
disableField: "<", // use '<' to generate input on the component
}
});
then in your app-form.html you can access the input var using the $ctrl object:
<form>
<input ng-if="$ctrl.disableField == true" type="text"/>
</form>
And the you can pass whatever value you want in the scope of your root view:
<div>
<!-- displays the form input according to the passed property's value -->
<app-form disable-field="isFieldEnabled"></app-form>
<!-- displays the form input -->
<app-form disable-field="true"></app-form>
<!-- does NOT display the form input -->
<app-form disable-field="false"></app-form>
<!-- does NOT display the form input, as disableField is evaluated an NULL in the component instance -->
<app-form></app-form>
</div>
isFieldEnabled is the property in your root controller $scope that will control the enabling / disabling of the input field in your component, but you can simply pass true or false if no logic is used.
You can attach whatever property you want, it doesn't have to be a boolean (but in this case I think it makes sense).
Also, notice that when defining the binded property 'disableField' in the Javascript environment, we use camelCase. The same property will be defined in the view / html environment using kebab-case.
You can also check the following answer to see how to generate output from the component instances:
Angular.js, how to pass value from one component to any other

Are react JS attributes different from properties?

I'm reading the react JS documentation and came across this:
Specifying Attributes with JSX:
You may use quotes to specify string literals as attributes:
const element = <div tabIndex="0"></div>;
I'm fairly comfortable with javascript but I'm not quite sure what the documentation means by "attributes". I know about object properties but this looks like a simple variable.
What exactly is a react js attribute if it is different from a property?
html elements have both attributes and properties
there are a few different scenarios for how they relate to each other. There doesn't necessarily have to be both an attribute or property for each value set on an element.
1. attributes
attributes can be set in html
<a id="mylink" href=""/>
where href is an attribute
or attributes can be set by using the set attribute method of an element
document.getElementById("mylink").setAttribute("href", "")
and read using
document.getElementById("mylink").getAttribute("href")
2. properties
properties can be set and read by retrieving the element as well
document.getElementById("mylink").href = ""
where href is a property
when they are set the first way, you are setting the attribute, the second sets the property.
Usually the underlying element attribute and property are
automatically synchronized, sometimes they are not.
Sometimes there is no matching attribute or property,
only one or the other exists.
Attributes and properties are part of native html elements, which React provides additional support and abstractions around.
Custom React components (such as <MyComponent prop=""/> or <MyComponent prop={someVar}/>), which you create yourself, accept props using the same syntax. The word props in this context refers purely to React props. React custom component props are just plain javascript values passed into your component. These custom components don't get added to the page. They are used to organize and render actual html elements.
When mounting a native component inside of a custom component (such as <div id=""/> or <div id={someVar}/>), the React library sets the underlying html attribute on the native browser element.
So there are two things to keep in mind here
html element attributes verse html element properties.
custom element props are neither of those, but setting a prop on a JSX
native element such as a div, set's the generated element's
attribute.
Now that's been established, the documentation above is saying: if you want to set an attribute value to a string you can use that specific syntax. That syntax only works for setting attribute values to strings.
You can use either:
<div id="myid"/>
or
<div id={'myid'} />
to set a string attribute value. They're probably just pointing out the syntax differences.
if you do:
<div tabIndex="0"/>
the value of tabIndex is the string 0 not the number zero
verses this:
<div tabIndex={0} />
which will pass the number zero to the tabindex attribute of the underlying html element
To me if we pass any parameter in function component then what we diclare in html is properties.But if you use (className/style/etc...) directecly in html then it will be attributes.

How to pass variable query parameters with a routerLink in Angular 5

Within an *ngFor loop, where I'm building a list of search results (mat cards) with sample reading texts, I want to allow the user to click on one of them to read more, and open a route to a document template populated with the right doc.
This static HTML works with routerlinkactive catching the params in the docview page...
<button mat-button [routerLink]="['/docview', {sDocName: 'AW010001'}]">READ MORE...</button>
I want to replace the hardcoded Doc ID 'AW010001' with the appropriate ID for each iteration through the *ngFor. But this code fails...
<button mat-button [routerLink]="['/docview', {sDocName: '{{sDocIDs[i]}}'}]">READ MORE...</button>
The error I get is the typical...
Parser Error: Got interpolation ({{}}) where expression was expected
at column 25 in [['/docview', {[sDocName]:'{{sDocIDs[i]}}' }]]
Check out Angular 5-Routing (Practical Guide)
To high-light the main points:
Update the route table:
{ path: 'book/:id', component: BookDetailsComponent, }
Use this format:
<a [routerLink]="['/book',b.Id]">Details</a>
So in your example I think it should look like this:
<button mat-button [routerLink]="['/docview', sDocIDs[i]">READ MORE...</button>
With ngFor loop i guess that you only need something like this : routerLink="/docview/{{sDocName.sDocIDs}}" + proper function in component
Go to angular.io, example is shown in tutorial
Actually... I ended up moving the routerLink functionality into a function in my .ts file for that component...
readMore(sDoc: string) {
this.router.navigate(['/docview', {sDocName: sDoc}]);
window.scrollTo(0, 0);
}
Then in my HTML, I use a variable that is associated with all the other story metadata... in this case I used an array for development, but will eventually replace that array variable with an element of a data model for the stories.
<button mat-raised-button (click)="readMore(DocIDs[i])">READ MORE...</button>
This is working well for me.

React JS element class names not rendering

Working on a pre existing React JS project and the className attribute does not render in the DOM what is defined.
For example - here is what code looks like in the project:
<div className={styles.intro_inner}></div>
Here is the output in the DOM:
I'm expecting the class name "intro_inner" to appear within the DOM.
Within JSX, the syntax attribute={variable} on a component means that the attribute will be set with the value of the given variable, not it's name. I would assume that your code has an object named styles which has an attribute named intro_inner whose value is some random mash of characters that you see output in the inspector.
If you want the class to be set as "intro_inner" then you need to set it as a string, not a variable. The syntax for that would be className="intro_inner".

Angular 2: Is it possible to use the same parent component with different child components?

I would like to know if is it possible to define a parent component without specifying which child component to use?
Normally i would create a parent component and use the selector of the child component in the html file
parent-component-1.html:
//some logic
<child-component-1-selector></child-component-1-selector>
//some logic
If i follow this approach i have to define which kind of child component i wanna use. But if i wanna use the parent component multiple times with different child components, i have to copy the logic part and create separate parent-components:
parent-component-1.html:
//some logic
<child-component-1-selector></child-component-1-selector>
//some logic
parent-component-2.html:
//some logic (same as above)
<child-component-2-selector></child-component-2-selector>
//some logic (same as above)
I don't like the approach because i would generate code duplicates. Is there a way to define the parent-component without specifying which child component to render and just 'pass' the child component as an argument?
current approach,
grand-parent-component.html:
<parent-component-1></parent-component-1>
<parent-component-2></parent-component-2>
suggested approach,
grand-parent-component.html:
<parent-component-selector [childcomponent] = "child-component-1"></parent-component-selector>
<parent-component-selector [childcomponent] = "child-component-2"></parent-component-selector>
I hope i have made my self clear about my 'problem'. Maybe you guys can help me and give suggestions about best practices
It sounds like you want to be able to do something like:
<my-custom-panel>
<here-is-one-inner-component>
</my-custom-panel>
And then in another place,
<my-custom-panel>
<some-other-component>
</my-custom-panel>
If i'm reading you right, then you're basically looking at using Angular's content projection.
So, in my example above, I'd write my-custom-panel component to look like this:
#Component({
selector: 'my-custom-panel',
template: `
<div class="wrapper">
<h1>My Heading</h1>
<ng-content></ng-content>
</div>
`
})
export class ....
The trick is that <ng-content> tag, which acts as a marker in the component's template. When using my-custom-panel in another template, any content that appears within the my-custom-panel tag will get projected right next to that <ng-content> tag.
Hopefully, an example will make things clearer. So, in the case of my first example, where the template using my-custom-panel is:
<my-custom-panel>
<here-is-one-inner-component>
</my-custom-panel>
That will get transformed into:
<div class="wrapper">
<h1>My Heading</h1>
<ng-content></ng-content>
<here-is-one-inner-component>
</div>
Is that what you're looking for?

Resources