How to display an array of objects in with typescript? - arrays

I'm very new to typescript.
I've got a wrapper component, and a bunch of child components that I want to display.
So, something like this is in my parent component html: <component-card [someData]=someData></component-card> works just fine and displays my component. But how do I display a list of them?
Simply doing <li *ngFor="let card of componentCardArray"></li> doesn't work. I tried different ways
Most tutorials just cover simple types, I searched for hours and can't find a way to do it.

Okay, I figured it out! I was forgetting to put the selector after the whole *ngFor directive thing. So, here is how my components are displayed now in my wrapper.html:
<div *ngFor="let card of cardArray">
<component-card [myData]=myData></component-card>
</div>

Related

access to child element in tailwind reactjs

Could you tell me the way to do something like this in tailwindcss:
first[&>.a-child-class]:text-5xl
I'm trying to style the first element by the way passing classes when it's rendering,I want to change its child's style, but the code above did not work.
I tried to put that classes inside component by default, but I realized, the component need to reusable, so that it is not reasonable.
please help meeeee.
thank you so much, have nice day.
In tailwind 3.1, arbitrary variants can be stacked with built-in modifiers or with each other, just like the rest of the modifiers in Tailwind. You can see the document here. You are missing : after first.
Example:
<div className="first:[&>.a-child-class]:text-5xl">
<p className="a-child-class">first</p>
<p className="a-child-class">second</p>
<p className="a-child-class">third</p>
<p className="a-child-class">forth</p>
</div>
Tailwind Play demo

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?

List of directives and transclusion

I'm trying to build some navigation directives to isolate complexity. I want the following HTML to render my navigation:
<custom-nav>
<nav-item>Item 1</nav-item>
<nav-item>Item 2</nav-item>
<nav-item>Item 3</nav-item>
</custom-nav>
If I wrote the directives right now, the resulting compiled HTML would look like this:
<custom-nav>
<nav>
<ul>
<nav-item><li><a>Item 1</a></li></nav-item>
<nav-item><li><a>Item 2</a></li></nav-item>
<nav-item><li><a>Item 3</a></li></nav-item>
</ul>
</nav>
</custom-nav>
however, this is invalid HTML (<ul>s can only have <li>s as children).
Without using replace: true, what is the best way for me to tackle this? The only things I can think of are:
Don't use <ul> or <li> - use aria roles to define my own list items.
Don't make the list semantically a list. I really don't want to do this.
Is there something I'm overlooking?
I am not sure if I understood the issue correctly, but what I can say is,
you can pass the items you want to use as li, in an array, as a parameter to the directive, and loop over it in your link function to generate the recommended html result, that would remove any complexity related to the issue
please let me know if I misunderstood you.
Best of luck

ng-click not working inside ng-switch

I'm beginner with AngularJs, and i have a lot of questions :/
Here's one of them :
I have links that i use to filter data. So when i click on link one, the value for the filter myFilter is one, etc.
Just to show you that my filters work, i putted two times the links (see here http://plnkr.co/edit/2G6mahkmyIixMJ1mEVKp?p=preview)
In the above links, i use ng-swich, cause i want, when i click on a link, to remove the link and only keep the text
In the bottom links, there are no ng-swich, so myFilter works perfectly
Is it possible, to make the ng-click inside the ng-swich work ?
The way you are approaching the issue involves far too much code duplication.
Also it is a bad practice to replace objects directly in the html. If you use a function bound to the scope it is cleaner and you won't run into child scope issues as much
Rather than creating four <ul> you could simply use ng-if within each <li> and use only one <ul>. This would also be a good case to create a very simple directive
HTML
<li>
<span ng-if="myFilter.trimestre==1">Avril - juin</span>
<a ng-if="myFilter.trimestre!=1" ng-click="updateFilter('trimestre',1)" href="#">Avril - juin</a>
</li>
JS
$scope.myFilter={};
$scope.updateFilter = function(key, val){
$scope.myFilter[key]=val;
}
DEMO

How should I integrate my directive and scope object in the view?

In my controller I have an array of objects. The object is called Well has a few properties, one of which is Location, which stores a string like "A1", "B4", "B13", etc. The location indicates a position on a grid. The letter represents the row, and the number represents the column.
Now that I have this nice list of objects, I would like to display them all on a grid in my view. When I say grid, I mean that loosely. The grid I have come up with is a series of divs, each with an id equal to a location name.
I have created a directive called tile that will display the properties of a single object. The directive looks like so:
<div class="row">
<div class="col-md-3" ng-repeat="well in wellArray">
<ul><li ng-repeat="prop in well">{{ prop }}</li></ul>
</div>
</div>
Great! And then I can create a tile in my view for a specific Well in the list of Well objects like so:
<div tile name="{{my.getName()}}" dil="{{my.getDilution()}}"></div>
If this list of objects was ordered by the location property, I could simply turn it into an array of arrays, one array for each row, and then use a double ng-repeat in my view. Unfortunately they are not in order, and I do not want to create a sorting method given the format that the location property is in. If i were to do the double ng-repeat on this list as it is now, I would end up with a grid of tiles that are in no particular order.
Given my limited exposure to javascript, I thought of using jquery's .append() method.(note: i have referenced jquery before angular, so angular.element() will use the jquery library instead of jqlite so I can use jquery selectors) In my view I created a bunch of divs in the following format:
<div id="A1"></div>
<div id="A2"></div>
etc.
And then in my controller I created a method that attempts to append a single Well which has a location of "A1" to the element on the view that has an id="A1". My code looks like so:
angular.element('#A1').append('<div tile name="{{my.getName()}}" dil ="{{my.getDilution()}}"></div>');
I thought it would append the div with the tile directive, to the div with id="A1", however, it does nothing. In fact, there are no errors at all.
Surely my psuedo jquery approach is not the best way to go about this. Not only is it not working (no idea why, maybe because angular needs to compile something somehow), but it's also not a very Angular approach. I keep reading in tutorials and introductions to "not use jquery at all for the first few weeks" and "90% of the things you'll waste lines of code in jquery, can be done suceinctly in Angular". Someone please lend this poor excuse of a programmer a hand!!
Just following your example in comments with .append, instead of iterating over your array and appending elements to a container element, create a conceptual representation of the data, and then use it in the view.
In controller, do something like the following:
$scope.wellData = {};
for (well in wellArray){
var key = wellArray[well].getLocation();
$scope.wellData[key] = well;
}
Then in the view, do ng-repeat over wellData:
<div id="item.getLocation()" ng-repeat="item in wellData">
<div tile name="{{item .getName()}}" dil="{{item .getDilution()}}"></div>
</div>
You definitely should stay away from jQuery in controllers. Just assume that there is no DOM in controllers whenever you get the urge to do anything related to DOM. Controller deals with ViewModels which are conceptual representation of the view, but it is view-independent. Whenever you break that separation, you make your controllers harder to test, and you make your view more difficult to change. And, by going against MVVM principles, you will keep bumping into issues with AngularJS.

Resources