angulardart components - dispatch custom event - events

I want to dispatch a custom event from my Angular Dart component to his parent. How can I do this with Angular Dart?
In other words I want do something similar to this: How do you dispatch and listen for custom events in Polymer?

Maybe emit does what you want but I assume this works only within Angular.
If you want to send DOM events you can do it with dispatchEvent method like
Element e; // assigned by the injector through a constructor argument or aquired by querySelector, ...
...
var event = new CustomEvent(
type, /* 'myeventname'
canBubble: canBubble != null ? canBubble : true,
cancelable: cancelable != null ? cancelable : true,
detail: {'somekey', 'someValue'}
);
e.dispatchEvent(event);
You can listen for this event by
e.on['myeventname'].listen((e) => print(e.details['somekey']));
or in Polymer (because I saw that you tried to make Angular work together with Polymer)
<some-element on-myeventname="{{myEventHandler}}"></some-element>

Related

How to listen to variable event in Meteor Template event?

The question basically is how to convert this:
var evt = 'click' || 'touchstart'; // Based on some logic
$('.selector').on(evt, function(){});
into Meteor event handler
Template.MyTemp.events({
....??? : function(e, t){}
});
UPDATE
Based on the comments below, seems like chrome is the problem, as it sets the touch events passive = true.
So the new question would be:
How to set the passive property for event listeners in Blaze Template
Events?
You can specify multiple events in a single handler by using a / as a delimiter between the event types. docs
Template.MyTemp.events({
'click/touchstart .selector'(e,t){
e.preventDefault(); // prevents default click after touchstart
// your handler
}
});
In english:
for the template MyTemp handle click or touchstart events on the
selector class.
This is also useful reading: touch and mouse

Event Registration in UI5 - attaching multiple listeners to an event

How can I add multiple event listeners to an event in UI5?
We have a master list with a dropdown that is correctly firing a select event on its controller. Sub controllers also need to be informed that this dropdown has changed in order to reload model data.
onAllRolesChange: function(oEvent) {
var key = oEvent.getParameter("selectedItem").getProperty("text");
if (this.ScreenId != null) {
this.loadScreenByRole(key);
// I could invoke the controllers directly, but that seems wrong
// controller2.update();
// controller3.update();
}
},
I assume what I should be aiming for is to call some sort of registerForEvent() method in each of the controllers, but I don't see anything like that in the SDK. fireEvent() and attachEvent() exist, but the examples I've seen appear to be for creating custom controls, or responding to browser events that SAP hasn't implemented.
As of UI5 1.65, multiple event handlers can be assigned when creating ManagedObjects / Controls:
(...) ManagedObjects now accept an array of multiple event listeners for an event. To
distinguish this use case from the already supported array with [data, listener, this], an array with multiple listeners must use nested array notation for each listener as well [in JS]. In XMLViews, multiple listeners have to be separated by a semicolon. (source)
Syntax
In XMLView
<Button press=".myControllerMethod; .mySubController.thatMethod" />
In JS
new Button({
press: [
[ listener1 ], // 1st listener
[ data, listener2, thisArg2 ] // 2nd listener
]
});
Demo
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/mvc/XMLView"
], XMLView => XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
height="100%"
displayBlock="true"
>
<Button text="Press" class="sapUiTinyMargin"
press="alert('1st event handler'); alert('2nd event handler')"
/>
</mvc:View>`,
}).then(view => view.placeAt("content"))));
<script id="sap-ui-bootstrap"
src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core, sap.m"
data-sap-ui-async="true"
data-sap-ui-compatVersion="edge"
data-sap-ui-theme="sap_fiori_3"
></script>
<body id="content" class="sapUiBody"></body>
You could use the EventBus to inform about the change, and who ever wants could listen for the change. However, if the other controllers are not yet loaded they won't get the events of course... Maybe you can combine this with promises...
You could also use a global model with 2 way binding and use it for your dropdown. When ever the dropdown changes the change is reflected in the corresponding model. At the same time, in your sub controllers you could create a sap.ui.model.Binding(...) for the same global model + path etc used for your dropdown. Additionally, you would attach a handler for the change event of the Binding... That should work as well. However, this has the same disadvantage like using the EventBus, but maybe thatÄs not an issue for you...

How to Include events (not event-plugin) in Ractive initialization/defaults?

I've read through the Ractive Documentation and I'm scratching my head a bit, because it seems like the default events initialization option allows me to do something - create new eventtypes - far more complex than what i need but conversely, there's no hook for the simpler, (more common?) task of defining default events
Could someone advise on how to provide global events that could be fired for traditional DOM events?
Example:
I have a 3 Component application page. I want to define a getOptions event, such that any <select on-click='getOptions'>...</select> will be handled by the same function. I don't want to have to define that function in each component.
My intuition would have been to do the following:
Ractive.events['getOptions'] = function(event){
//logic for getting the options for the value in event.keypath
}
or, if i wanted a true default that could be overridden...
Ractive.default.events['getOptions'] = function(event){
//logic for getting the options for the value in event.keypath
}
but my understanding of the documentation, is that Ractive.events and Ractive.default.events do not provide this, but rather provide a way to define new event plugins, that depend on a separate mechanism for getting fired:
Ractive.events.getoptions = function(node,fire){
//here goes logic for interacting with DOM event listeners, etc
}
//and then i would need to do this
ractive = Ractive.extend({...});
ractive.on('someOtherEventName',function(event){
//logic for getting the options for the value in event.keypath
});
//and then I could do this...
<select on-getoptions='someOtherEventName'>...</select>
but what would fire the getoptions in this case - from the template, rather than js ractive.fire()?
Would something like <select on-getoptions='someOtherFunction' on-click=getoptions>...</select> work? That seems very strange to me. Do I understand the concept correction? If not, what am i missing?
Is there a simple way to achieve the first example?
Ractive.events refers to custom events for mediating between the dom and the template:
Ractive.events.banana = function( node, fire ) { ... };
<div on-banana="doSomething()"/>
The handler for the event can either be the name of an event to fire, or a method on the component instance.
In your case, I think defining a method on the Ractive.prototype would be the best way to have a common handler:
Ractive.prototype.getOptions = function( /* pass in arguments */ ){
// and/or this.event will give you access
// to current event and thus context
// you can also override this method in components and
// call this base method using this._super(..)
}
// now any ractive instance can use:
<select on-click="getOptions(data)">...</select>
An event based approach usually entails letting the root instance or common parent in the view hierarchy handle same event across child components:
var app = new Ractive({
template: "<componentA/><componentB/>",
oninit(){
this.on( '*.getOptions', ( event, arg ) => {
// any child component (at any depth)
// that fires a "getOptions" event will
// end up here
});
}
});
// in component A or B:
<select on-click="getOptions">...</select>
UPDATE: If you wanted to assign an event handler to the prototype, so in essence every component is pre-wired to handle an event of a set name, you could do:
Ractive.prototype.oninit = function(){
this.on( 'getOptions', ( event ) => {
// handle any "getOptions" event that happens in the instance
});
}
Just be aware that you must call this._super(); in any component in which you also implement oninit:
var Component = Ractive.extend({
oninit() {
// make sure we call the base or event listener won't happen!
this._super();
// do this component instances init work...
}
}

How do I create an`Event` instance with the `target` property set?

When I subscribe to the onChange event of an InputElement, the event type is Event and has the target property set:
new InputElement()
..onChange.listen((e) {
print(e.runtimeType);
print(e.target);
});
How do I copy this behavior (for my own custom input box) and create events with the target property set?
None of the Event constructors allow you to pass a target, and the target property is get-only.
I tried finding the source for InputElement to see how it worked; but was unable to locate it in the Dart repo :(
I think you should use a CustomEvent instead.
dispatchEvent(new CustomEvent('nameOfEvent'));
Just call dispatchEvent from the element you want to have set as target
final someDiv = dom.querySelector('#some');
someDiv.dispatchEvent(new dom.CustomEvent('xxx-yyy'));
In this question it is shown how to do it in Polymer elements How do I fire a custom event from Polymer Dart?
You do this by calling dispatchEvent on the element, passing the Event:
var e = new Event.eventType('Event', 'change', canBubble: true, cancelable: false);
dispatchEvent(e);

Which events can be subscribed to with Knockout's observable.subscribe function

Under the Explicitly Subscribing to Observables section of the Knockout documentation, there is a reference to an event parameter of the subscribe function, but the only two examples given on that page are change and beforeChange.
By way of example, I tried passing in "focus" as the third parameter but that didn't work. I'm not too surprised as "focus" is an event of a DOM Element rather than a knockout observable, but nonetheless it could theoretically have setup a subscription to the focus event for all elements bound to that observable.
Is there a list of all events that can be subscribed to manually using Knockout's observable.subscribe function?
It make sens to use "event" binding in your case.
Because there are only two ways to notify subscribers of observable variable: beforeChange and change.
In knockoutJs code there is simple chain of if blocks which check if event is specified, and if event is equal to beforeChange. That's basically all logic which goes there, so no other events fired.
Part form knockoutJS which implements this logic:
self["notifySubscribers"] = function(value, event) {
if (!event || event === defaultEvent) {
self._rateLimitedChange(value);
} else if (event === beforeChange) {
self._rateLimitedBeforeChange(value);
} else {
self._origNotifySubscribers(value, event);
}
};

Resources