Angular 6 - Best way to implement complex template - javascript

I'm relatively new to the Angular 2.0+ world, and I'm facing a question about template design. I'm sure there's an Angular way to do this; I just didn't find a clear answer yet.
So, the idea is that (see the attached image) I've the red component, that has to be included in many parts of the application. The red component has some styles, inputs and outputs that are gonna be the same for the whole app. But inside the red component there must be embedded three components that will vary depending on where the red component is placed.
For example, imagine the red component is the container for a detail page. If it's placed in the detail page of the entity A, green component will be a map, yellow an image and blue a read more button. All of those components must have inputs, outputs and probably references so they can be manipulated using view childs.
If the red component is placed somewhere else, then those three components will be different. And there could even be just 2, not three components.
Does someone has a clue on how to design the red component so it's reusable and can fit my necesities? Thanks a lot, and please let me know if more explanations are required for my problem to be understood.

In this case you can use named ng-content, where you can more than one component as its container data and pass input/events/style or whatever you want to pass for example -
<red-component>
<yellow-component></yellow-component>
<blue-component></blue-component>
<green-component></green-component>
</red-component>
https://medium.freecodecamp.org/everything-you-need-to-know-about-ng-template-ng-content-ng-container-and-ngtemplateoutlet-4b7b51223691

Related

Triggering a drawing on canvas from another ReactJS component

I'm currently trying to learn ReactJS and wanted to work on a little project to ensure I've learnt the fundamentals .
The structure of my ReactJS application is something like this:
<App>
<MainCanvas/>
<CommandPanel>
<CommandButton/>
<CommandButton/>
<CommandButton/>
</CommandPanel>
</App>
MainCanvas contains an HTML5 Canvas. CommandPanel passes a prop down to each CommandButton. Inside the CommandButton.js file, I have an array of objects which serves as a lookup to tell the button what text to render. All the components here are functional components and sit in their own JS file.
In addition to this, I also have another JS file called 'CanvasFunctions.js' which contains some routines that draw lines on a canvas. Let's say it has two functions: DrawCircle and DrawSquare.
What I'd like to do on click of the buttons, trigger a function in the CanvasFunctions.js file that draws onto the canvas. Also note that I'd like to have access to the path information in the future so I can modify the paths by moving them around the canvas. When I click one button it triggers the DrawCircle function. Then I can click the next button and it triggers the DrawSquare. The square should be drawn on top of the circle and not clear the canvas. However, I'm not sure what the correct way of going about this is.
There was a lot of useful information here, however, all the code is under a single Canvas element and given what I'm trying to do, I don't think I should be coding it that way.
This seems to be very similar to what I'm trying to do.
Do I pass down a callback function in App down through CommandPanel to each CommandButton (adding it to the lookup object so I can generate these buttons dynamically) that gets called with onClick? If so, how do I get App to trigger a function on MainCanvas? It also doesn't seem to be the "correct" way of doing this. My understanding is that parents need to pass props to children and callbacks. They shouldn't be triggering methods in children components.
Could someone point me in the right direction of what I should be doing?
Thanks
Edit: Been thinking about this some more. Maybe a restructuring of my application? Moving the CommandPanel into the MainCanvas. That way, I can set up functions inside MainCanvas and pass them via props to the CommandButton elements below. Maybe that would be a better approach? And if it is the way to do it, how do I set the names of the callback functions into the lookup object so I can only pass one prop to the button and lookup the name of the callback function from the object?

React - component for every styled element?

I'm learning React.
It seems React highly promotes composition. Create React App even advises against reuse of css class.
Let's say I have a container, which is a white box, with nice rounded corner and shadow, etc. It can contain anything. That's it. No logic. Not much html except a <div>
Traditionally, I would just create a global css class named .white-box and then apply it to any <div> that I want it to be this white box.
I know in React you can do this, too. You can do whatever you want. But what is the general practice? From what I found online, it seems I should create a component for it and put any children inside:
<WhiteBox>
<div>anything</div>
</WhiteBox>
Isn't it overkill? What are the benefits of doing this? Should I create a component for everything that can be re-used, even when it is such a small thing?
This is honestly a matter of personal preference and experience.
For example, the seemingly pragmatic way would be to use a .white-box class on a div; it's super easy and requires no imports!
A bit later down the line, you decide that every white box inside some other control needs a bit more shadow, so you go and add a CSS rule for .some-component .white-box, and bam, now you got a shadow'ier white box without messing with the original CSS class. Nice and easy!
The problem with that is that when you do it once or twice, it's fine. But you'll soon develop a habit for "patching" the class name rules for specific purposes, and before you know it you're mixing rules without knowing it yourself, which is exactly what it says on the tin: Cascading Style Sheets.
I've been there myself, and it's no fun to maintain. Now I create components for everything, even things as simple as a white box. The trick is to name them right; you wouldn't call it WhiteBox because if you change the color of the box down the line, the rest of your code is a lie. ;) Instead, call it something like ContentBox; something that describes it's purpose, not what it looks like. Then use props to determine what characteristics the box should have:
<ContentBox shadow padded rounded>Awesome</ContentBox>
I'm personally a big fan of CSS Modules because they make sure that class rules never clash which avoids the issue outlined above entirely. Instead, if you want a class to inherit some styles from another, CSS Modules lets you compose them together.
Example CSS modules file:
.root {
background-color: #fff;
}
And a React component:
import React from 'react'
import styles from './ContentBox.css'
export default function ContentBox({ children }) {
return (
<div className={styles.root}>{children}</div>
)
}
The actual classname being used is actually something like ContentBox__root_abcd123random so even if you have another CSS file with the same .root class, the rules never clash.
An added bonus of doing it this way is that your components are now portable to other projects because it only depends on styling within the CSS file that ships with the component. I've enjoyed great reuse using this strategy across many internal web apps at our company.
That's right. It's not overkill when you are confident that features will be the same across your app. For example, you can have the nice shadow styles as you said, or guarantee that all containers have white background or might have a fluid prop which will expand the element for the whole parent width.
In fact, there are React frameworks like Semantic UI React that do exactly like this.
Every time you see yourself designing some HTML that should be consistent in your codebase, that should ring a bell for creating a single unique component for it. And if you think your components are big enough, maybe you should break them down.
This approach makes your code easy to test, once it's way more easier to test small stuff with limited and well-defined functionalities than a big component which several features. Once you glue them together, because of React one-way data flow approach, you know exactly why stuff is not working - you now have simple components for each feature, and if they are not working as expected, there is only one flow where data might have came.
As a beginner those concepts might be hard to grasp. But once you start digging into large codebases and projects, you will see how "modularizing" your application will have long-term benefits.

Angular 4 - it is more expensive to handle styles of a generic component or work with specific components

I'm working on a hybrid application for which I need a toolbar. This toolbar must handle different forms and functionalities, in some cases contains a title, other buttons and links and in others an autocomplete, then my questions is if is more efficient to build a dynamic component that accepts all these elements or work on different toolbar's that will be inserted and removed from the DOM as needed.
Thanks!
A dynamic toolbar will be faster, because angular wont need to re-render the whole toolbar each time it changes. It's smart enough just to find the stuff it needs to update.
Also it will make your code easier to maintain I think. Having multiple toolbars, probably with some shared logic/elements will cause repeated code.
Also you will probably have less lines of code with a dynamic toolbar, perhaps slightly reducing the size of your project. I suspect that wont be significant. Honestly, I think the biggest advantage wont be speed but cleaner, more maintainable code in general.
It depends on whether you are using lazy loading or bundling your entire App in one main.bundle.js
In the first case, you want to ship the strict minimum to the browser as it's needed. Therefore, you want separate component for each use case.
In the second case, it makes your app lighter to create on single component to handle different toolbar use cases.
To demonstrate this, (assuming you're not using lazy loading) you can create a small project with a main component which uses 2 different views.
In one case you create a single component for each view.
In the other you combine both views in one component.
Then build and serve both and you can see the difference in the weight of your JS files.
Hope this helps

Completely different view for mobile

I have a SPA that needs to display my app in two completely different ways depending on the client device.
One shows a floorplan of my house with lightbulb icons to switch on/off my lights (and later on more information), rendered on a canvas using isometric projection.
The other (mostly for mobile) shows the same lightbulb icons alongside a name in a simpler list/hamburger menu.
I don't want to limit either device-type to the view I intended, but what is the best way of completely replacing the component based on device/selected view?
Should I create two components and move shared logic to services/classes? Or should I hide the unneeded component (I don't want to waste resources rendering the canvas or running the logic needed to render it)
If you use *ngIf or similar, then there is nothing rendered if the expression is false while [hidden]="..." causes HTML to be rendered.
Moving logic to services is a good practice anyway.
You could also load different router configuration depending on the view size
See also New Angular2 router configuration. This way you could load entirely different components for different view sizes.
(It looks like this will be improved in next versions for example to only load new child routes for a component, there are also discussions to provide an API to allow to add/remove single routes)

React different representations of same data, parametrize container component render

Is it an antipattern to return different representation component elements from container based on some condition variable passed to the container?
I have routes for SummaryPageComponent and CustomersPageComponent. Summary page has a partition which presents chunk of the same data that Customers page shows in more detail. It would be redundant to create two distinct container components containing the same data and logic just to pass that data to different representation component. Including logic to representation component isn't an opinion either.
So my question is, would it be acceptable to create a container component which returns either <CustomersSummaryComponent> or <CustomersDetailsComponent> based on some prop (summary=true/false for example) passed to it? That way I could include the Customers domain anywhere in my SAP and parametrize it's presentation the way that fits. Is this advisable or does it make code too hard to maintain?
good thinking it is okay if done using High order components (HOCs) cause you can reuse the logic. eg a YouTube player can show small and large screen without the displaying component not knowing how to do it but just respond to behavior change in screen size, use High order components to abstract the logic: https://github.com/mathieuancelin/react-conditional-render and
https://medium.com/#franleplant/react-higher-order-components-in-depth-cf9032ee6c3e#.hebgpvtup

Categories