Send an event up multiple parents to trigger a function Angular 5 - javascript

I have a main-page.componenent.ts like so...
<app-page-component></app-page-component>
and then inside my app-page component I have another nested component like so..
<nested-compoennt></nested-component>
so basically my app looks like this
<app-main-component> // where the function is
<app-page-component>
<nested-component></nested-component> // where the button is
</app-page-component>
</app-main-component>
now I have a button in my nested-component and I want that to trigger a function on the top parent component.. now I know if I was passing an event to the most direct parent I could use an event emitter but Im not sure if that will work in this case.. so my question is how can I 'bubble' up an event so it hits the most parent container and triggers and event?
any help would be appreciated

You have two options.
The first option, you can have each component have an output that broadcasts the event up. This can get unweildly pretty quickly, especially if it is deeply nested.
The second option, you can use a shared service to send and receive messages. Essentially your component that has the button would call a method on your service that broadcasts out the event and your parent component would use the service to subscribe to these events that are broadcast out and act appropriately.

There are lots of cases and little bit hard to understand what your case is.
In my view,
There would be 2 opstions.
grandparent <=> parent <=> children : event emitter
(https://angular.io/guide/component-interaction#!#bidirectional-service)
using service : define service and call children components to set data or make events, and grandparent subscribe the value changes or event subscribe.
I hope this would be helpful :)

Related

Implementing a #hostListener only when component is called

Angular application that uses a ngx-datatable. This table auto populates its [rows]. Within these rows is an [action] that displays a popup of items. This popup is a seperate component away from the table. I am calling the popup from the table in a parent > child link e.g.
<ngx-datatable-column name="Actions">
<ng-template let-row="row" ngx-datatable-cell-template>
<app-actions-pop-up [actions]="row.actions"></app-actions-pop-up>
</ng-template>
</ngx-datatable-column>
This calls the action popup component. I have an #HostListener that listens to the clicks on the page for an Event. This then returns true/false to open or close the popup.
This is costly as my application will have 1000's of rows and it will impact the rendering as a click is being listened too regardless of whether the actions button is being clicked on.
e.g. if there are 4 row items, it will loop through 4 times. Imagine if there were 1000s of rows.
There is a lovely solution found here: Detect click outside Angular component where by it adds a #Hostlistener() to the document click event only once inside the popup component. The event should push the value of the clicked target element inside a public subject stored in a global utility service.
However, I have struggled to implement this thus far in my setup. Any help would be appreciated here - stackBlitz example
I would suggest simply adding (document:click)="clickout($event)" on your popup container.
html
<div *ngIf="isActive" (document:click)="clickout($event)" class="actions__container">
ts
clickout(event) {
this.isActive = this.eRef.nativeElement.contains(event.target);
}
Angular will subscribe to that event only in case if popup is open and unsubscribe when it's closed. So you will have zero or only one subscription.
You can also read one of my article regarding this optimization
Simple Angular context help component or how global event listener can affect your perfomance
Forked Stackblitz

Go back on a stack navigator passing params?

How do I navigation.popToTop() passing params to the initial route?
Inside of my screen I have a FlatList and I want to pass the string title of the list item selected to the initial route of the navigator.
You have two option to achieve this.
Using call back method
Add a callback method in root class and pass it to the child. Then cll the callBackMethod from child.
Add an event listener in root. And emit the listener from child.eg: https://www.npmjs.com/package/react-native-event-listeners
Hope this will help.

React-Native parent Node change children value

I am looking for all web but I no found any solution, maybe because I am newer with React-Native universe.
Well, my question is about Node Parent change value of Children.
My situation is, I have a data controller and this data controller listen data from events and when the events happen it need update a component like Slider.
the render need be.
<DataListener url={this.state.service_url}>
<Slider style={this.styles.slider_component}/>
</DataListener>
I need understand the cycle to get a default Slider with my Class DataListener. Is it with props in constructor? How can I get the slider inside DataListener and change this value like this.default_slider.value = 0.4
Thanks Advance
Victor C Tavernari
You should pass down the value as a prop and then your slider component can deal with it appropriately. Of course DataListener has to get the value in the first place and as you have detailed that let's assume it is in state (when you update state (via this.setState(newState)) it will cause a re-render of the DataListener which will in turn re-render the Slider with the new property):
<DataListener url={this.state.service_url}>
<Slider style={this.styles.slider_component} value={this.state.value}/>
</DataListener>
the data controller event you refer to would then be something like
onEvent(e) {
this.setState({value: e.value});
}

modalService cannot talk with controller and view

The code at this plnkr has a modal which pops up when a user clicks on a "Click to take quiz" button which calls a controller method that in turn calls a modal service. To get the plnkr to work, click anywhere in the code and press the space bar to add white space in a way that does not effect syntax. This will trigger plnkr to re-initialize the app and make the modal pop up after you click the button.
The problem is that the text printed in the modal does not update dynamically when timeLeft variable counts down. And also, the user's button click does not update the quizAnswer variable. In short, the modal is not able to talk interactively with the calling controller and view.
What specific changes need to be made to the plnkr to get the modal text to show the dynamic countdown, and to get the modal buttons to change the value of the $scope.quizAnswer variable?
Also, I have been carefully reading the documentation at this link. I think that the answer may be related to:
1.) $uibModal's options parameter passed in open(options) contains the parameter scope that defines the parent scope to be used for the modal's content, and also property bindToController which, when set to true, binds the scope property to a specific controller defined by controllerAs.
2.) The open(options) method returns a modal instance, which includes close(result) and dismiss(reason).
I suspect that the solution lies in these methods and parameters, but I am looking for good examples and would appreciate some experienced eyes looking at this problem.
NOTE: The solution to this came in the comments below the accepted answer, especially the link to another posting that contains 2 lines of code for emitting the modal button click's results back to the parent controller.
You have a number of issues.
First, takeQuiz at navigation.js - line 16, should be attached to $scope, not this, since this will mutate depending on context.
Second, $scope.$apply and $scope.$digst(); at navigation.js - lines 29/30 are unnecessary since you will already be in a digest cycle. They should be removed else they'll trigger an error.
Finally (and this is the meat of your issue), you are misunderstanding how modal options are bound across when creating a modal instance. It is NOT two-way binding; it is a single extends from one object to another. As a result, trying to bind to the options (or creating a concatenated string with the timeRemaining) will not update once it's bound across.
Instead, one possibility is to create an event handler inside of the modal and broadcast on each tick, updating the modal. In addition, if you pass the body text as prepend and append text, it is easier to insert your timestamp value:
You will need to inject (and broadcast from) $rootScope in your navigationController, since the modalService is registered somewhere very high in the scope chain.
On each tick, broadcast the time remaining navigation.js:
$rootScope.$broadcast('timeRemainingTick', $scope.timeRemaining);
In your modalService.js, register to receive the event inside of the controller assignment:
var timeRemainingUnbind = $scope.$on('timeRemainingTick', function(event, newTick) {
$scope.modalOptions.timeRemaining = newTick;
});
Finally, make sure that you unbind the event by calling timeRemainingUnbind() in the close events of your modal to prevent memory leaks:
$scope.modalOptions.ok = function (result) {
timeRemainingUnbind();
$modalInstance.close(result);
};
$scope.modalOptions.close = function (result) {
timeRemainingUnbind();
$modalInstance.dismiss('cancel');
};
See my working forked plunker here

BackboneJS: is there a list of default events one can bind to?

I know we can create our own events in Backbone.js like
object.trigger('myEvent');
I also know there are some default events like the change or change:<attributename>
now i'm wondering, is there a list somewhere of these default events?
i am looking for a specific event that triggers when someone navigates away from a view,
so either in the removing of the view, or perhaps when a route is changed,
I just hope i don't have to hack in my own event and it can't hurt to see a full list of these events for further reference.
update seems like the list did exist already, as benoit describes in the comment above,
it can be found here... http://documentcloud.github.com/backbone/#FAQ-events
so it seems such a list does not exist, well, i took it upon me to go through the annotated source and present the list here for everyone who might ever need it.
i do also make this a community wiki post, so i hope it will be updated by any of you who feel the need to. whether a new Backbone version comes with extra events or i've got something wrong, feel free to edit.
here goes the list of events triggered by backbone itself:
change:<attributename>
fired after using model.set({<attributename>, 'value'});
to indicate the attribute was changed.
change
fired after using model.set({<attributename>, 'value'});
to indicate the model was changed. this fire's on any attribute you change.
destroy
fires after you destroy a model, model.destroy({options});
error
fires after a model is validated and 1 of the validations fails,
if however a specific error callback function is passed in, that one will
be executed instead of the error event.
also fires when you do NOT give an error callback to the following model methods:
model.fetch();
model.save();
model.destroy();
reset
fired when a collection is sorted through the collection.sort({options}); method
also fired when specifically asking to reset a collection through collection.reset(models, {options});
add
fired when a model is added to a collection collection.add(models, {options});
remove
fired when a model is removed from a collection... collection.remove(models, {options});
The particular event you are looking for does not exist, but it can be added easily.
Backbone.View.prototype.remove = function() {
$(this.el).remove();
this.trigger('remove', this);
return this;
}
There is also a 'navigate' event built in, if you are using the Router.

Categories

Resources