3
aviophile
47d

A question about Angular components. Can a component become a member of another component?

Let' s say I have a sensorReading component that looks like these green boxes. I only want 4 of them in app-component(default one). How can I create 4 of these inside app-component and access their properties and methods from app-component.ts script?

I can create 4 of them in app-component.html with ngFor but how can I access elements of these sensorReading components I created with ngFor? Members are sensorType, value and unit as you can see.

Comments
  • 1
    Take a look into the content children decorator. It's very simple and easy to use.

    With that said breaking encapsulation is something you would only do for very specific reasons. I avoid it as much as possible.
  • 1
    Another way is to use a modern framework, like Vue :)
  • 3
    @ScriptCoded can't speak for Vue but i don't get hate on angular.

    I find .net far harder to learn than angular, yet .net is loved.
  • 0
    @craig939393 My aim is giving initial but not modifiable(at least intentionally) values to Sensor Heading and Unit values, changing SensorValue(in the middle) whenever new measurement is taken.

    I used Input decorator on these values and got over with it. But I do not know if that is the best practice in Angular. My intention was passing Heading and Unit as constructor parameter it was discouraged. But how can I set these once-set stays-same parameters beautifully?
  • 1
    @aviophile if it's a very small project, then content children might be the way forward. But I am not sure if you will get console errors if you set the values like that on NgOninit or other hooks. See change detection which is not complicated, but often hard to understand docs about.

    Other approaches include input and output bindings which will let the framework handle the change. Use ngonchanges in the components that you want to prevent changing values in and throw errors if it is not the first change.

    Final approach I can think of if you want to avoid the input and output bindings is use a service that holds state and DI it into all components. There you can use rxjs if you choose to, or just set synchronous properties.
  • 0
    @craig939393 Being hard to learn and over complicated ain't the same thing
  • 2
    @ScriptCoded
    Vue is at best 5 years behind angular in features and maturity.
  • 1
    I go a different approach, I create a central service that exposes a function which can mergeMap any number of incoming streams. Inject it into the children, pass a Subject<T> to the service. OnDestroy, complete the subject. You can even type the data by setting it's types to the union of things you want to observe.

    You can now share N services worth of data streams between any number of services. Inject it into your base controller and you're good to go.

    This keeps data one way, keeps data typed and you don't have to reflectively make parents aware of children.
  • 1
    @SortOfTested Perhaps I haven't used Angular enough (I haven't used it very much), but the web is bloated enough as it is
  • 2
    @ScriptCoded
    Not sure what you're referring to. My base payload is < 200kb uncompressed with all polyfills and everything lazy loads by route outside of that, with no discrete css payloads.
  • 1
    @ScriptCoded I believe there is also a way to limit bundle size by configuration. That looks neat.
  • 0
    @SortOfTested Oh well I rest my case
  • 0
    @SortOfTested Admittedly, I am tooo new when it comes to Web applications. Some of the things you said was not understood by me but I will check those keywords.

    Right now, I created an array of sensor-box objects(imported class definition from sensor-box component I use to represent those boxes) in parent component. In parent html, I added tags of sensor-boxes with input binding, so whenever I change values in object array in parent component, it dynamically updated sensor box values. It has side effects, I never intend to set sensor heading and units more than once but I could not find constructor like approach for now.

    But basic scenario is I will read a combined sensor output from HTTP streams?, and parse it and pass relevant values to different sensorBox components. It won't become more complicated than that.
  • 0
    @craig939393 Is there an Angular way to set those one time set parameters without using service or inout binding? Afaik, service and input binding allows to change those fields all the times, but I need a constructor like approach to the problem.
  • 0
    @aviophile you can't. But like I say, ngOnChanges gives a way to see if it's the first change or not. You can throw errors. This will at least show mistakes early and very clearly, if not prevent them.
  • 0
    Yeah since I am not going open source, all I have to do is setting them once I think.
Add Comment