programatically adding an on-tap attribute referencing a dart function for a HtmlElement - dart

I have a dart function:
_addSelection(HtmlElement ele){
ele.classes.add("selection");
}
I would either want 1 or 2 things to occur, either A) execute an on-tap and on-track function given the selection class.... OR Dynamically add the on-tap and on-track attributes referencing reflected dart functions.
I have 2 functions:
#reflectable
onTap(CustomEventWrapper cew, params){
//...
}
#reflectable
onTrack(CustomEventWrapper cew, params){
//...
}
I was looking at the HtmlElement class and documentation and I wasnt quite understanding how to do this.
Edit if I were using jQuery and Javascript, I would be doing something as simple as:
$(document).on("tap", function(){});
$(document).on("track", function(){});
Edit2 Added Angular Dart because both designs leverage Dart backend and markup front end.

You could do:
_addSelection(HtmlElement ele) {
ele.classes.add("selection");
ele.onTouchEnd.listen((TouchEvent touch) {
...
});
}
That would give you something close to the tap event. If you wanted to get really fancy you could also listen for onTouchStart and only call your onTap handler when the time between the start and end is small.

Related

Are listeners like <svelte:window on:keydown={handleKeydown}/> component scoped or global?

If I add a key listener inside a component using
<svelte:window on:keydown={handleKeydown}/>
as per https://svelte.dev/tutorial/svelte-window , is the listener removed when the component is destroyed? I want to be sure I am not causing memory leaks of any kind.
Yes, if you want, you can look at the generated JS code and you will find this:
m(target, anchor) {
dispose = listen(window, "keydown", /*handleKeydown*/ ctx[0]);
},
...
...
d(detaching) {
dispose();
}
The m() method is the mounting function and the d() is the destroy. You can see the listener is added in the m() and then it is removed in the d(). This is simplified but you can find out more by investigating the Svelte source code :)
Good luck!

iron-ajax on-response doesnt recognize dart reflected method

My ajax is defined as:
<iron-ajax id="myAjaxId" auto
url="http://localhost:8088/test_server/v1/users/35"
handle-as="json"
on-response="{{handleResponse}}" ></iron-ajax>
and in my dart i say:
#reflectable
void handleResponse ( e, Map data ){
print("hand response fired");
f_name = data["f_name"];
l_name = data["l_name"];
id = data["id"];
}
not only does it not fire the print statement, but in the Chromium console, when it is run, it says:
[my-ajax-fetcher::_createEventHandler]: listener method `{{handleResponse}}` not defined
I was looking up some other examples and noticed #reflectable is the tag i should be applying.
I was also trying to look up what the target signature needs to look like, and didnt see anything.
You don't need {{}} for event handlers in Polymer 1.x just on-response="handleResponse"

Do something after attribute value got assigned

I would like to do some mapping after the members have been set by angular dart:
#Component(
selector: 'travel-step',
templateUrl: 'packages/TravelPlanner/travelstep/travel_step_component.html',
useShadowDom: false,
publishAs: 'cmp')
class TravelStepComponent {
// Deprecated but impossible to replace, since the new syntax is not ready
#NgTwoWay('step')
TravelStep step;
TravelStepComponent() {
// step is null at the moment
}
}
I'm using angular v. 0.12. When the constructor is called, step is still null.
I could do it with a watch expression but I only want to do it once, so this workaround is not how I want to do it.
You can implement AttachAware and put your code into the attach() method.
Similar behavior can be achieved by implementing ShadowRootAware and onShadowRoot().
You need to give Angular some time to evaluate the bindings and assign the values. Use one of these methods according to your requirements.
Sometimes it might help to (additionally) wrap your code into a
new Future(() {
your code here
});
to delay the execution of your code.
Another approach is to implement a setter and execute your logic there
#NgTwoWay('step')
TravelStep _step;
TravelStep get step => _step;
set step(TravelStep s) {
// your code here
_step = s;
// or here
}

Provide callback for custom component

I made a custom component which basically wraps a d3 line chart. Now I want to be able to register a callback for clicks on the lines in the chart.
I gave the component a #NgCallback parameter, which I then send events to:
class NetworkSummaryComponent implements NgShadowRootAware {
#NgCallback('callback')
Function callback;
void onShadowRoot(ShadowRoot shadowRoot) {
...
chart.callMethod('listen', ['line-click', (ev) {
var name = ev.callMethod('getLineName');
print(name);
callback({'name': name});
}]);
}
}
When using the component, I specify a function of my controller as callback:
<network-summary
...
callback="ctrl.lineClicked">
</network-summary>
However, that function is never actually called, put I know the callback arrives from the JS side because the print in the first snippet is executed.
If I instead specify the attribute as callback="ctrl.lineClicked()" I get a strange exception:
Closure call with mismatched arguments: function 'call'
I could not find any official documentation on how to properly do callbacks, so I'm not exactly sure what I'm doing wrong.. Any ideas?
It turns out that I had to explicitly name the expected arguments in the attributes:
<network-summary
...
callback="ctrl.lineClicked(name)">
</network-summary>
Hope this is useful to the next person having this problem.

calling jQuery .remove() on custom UI widget causes infinite loop

I have created custom jQuery UI widget called uiPopover, very similar to UI-dialog (in fact, most of the code is copy-paste from it). This widget has a custom destroy method that hides the widget and removes it from the DOM. Again, it's pretty much copy-paste from UI-dialog.
destroy: function() {
var self = this;
if (self.overlay) {
self.overlay.destroy();
}
self.close();
self.element
.removeData('popover');
self.uiPopover.remove();
console.log('afterRemove')
return self;
},
The weird thing is that this causes an infinite loop that throws some errors:
$('#element').popover();
$('#element').remove();
As far as I can see, the problem is that when I call .remove(), it automatically calls destroy() on my widget (this is built-in in jQuery UI) and the destroy methodd tries to call remove() again on my element, and then that tries to call destroy() again and so on..
However, the weird thing is that this doesn't happen with UI dialog. So when I do this:
$('#element').dialog();
$('#element').remove();
Everything is okay... There must be something wrong with my plugin, but I cannot figure out what.
Here is the full source of my plugin: https://gist.github.com/2208569
There's not much you can do about the recursive call to destroy(), aside from modifying jQuery UI itself. You can, however, break the chain by preventing remove() from being called again:
destroy: function() {
var self = this;
if (self.overlay) {
self.overlay.destroy();
}
self.close();
if (self.element.data("popover")) {
self.element.removeData("popover");
self.uiPopover.remove();
}
return self;
}
Note in passing that you don't have to copy and paste code in order to augment existing widgets, as the widget framework supports prototype inheritance. It would be interesting to know if your problem still occurs if you have your widget derive from $.ui.dialog instead of duplicating its code base.

Resources