Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dart JavaScript interop callbacks with jQuery

How can I translate the following jquery code to Dart? I'm having difficulty getting the alert callback to work using js.interop.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
  $(function () {
    $('p').hide('slow', function() {
      alert("The paragraph is now hidden");
    });
  });
</script>

Any help is appreciated.

like image 837
basheps Avatar asked Nov 04 '12 22:11

basheps


2 Answers

thanks for your question! I wasn't sure myself, but turns out this is possible. :)

First off, add js to your pubspec.yaml:

name:  jquerydart
description:  A sample application

dependencies:
  js: any

Then, run pub install, either via the command line or via Dart Editor.

Then, in your Dart file:

import 'dart:html';
import 'package:js/js.dart' as js;

hideIsDone() {
  window.alert('all done!');
}

void main() {
  js.scoped(() {
    js.context.jQuery('p').hide(1000, new js.Callback.once(() => hideIsDone()));
  });
}

Note that to callback from JS into Dart, you need to create a Callback object.

Also note you cannot use $ for the jQuery variable, as dart2js also uses $. So in the meantime you need to use jQuery in your Dart code.

Having said all that, it's cool that we can use jQuery via JS-Dart interop, but Dart should really do this for us. So I opened bug http://code.google.com/p/dart/issues/detail?id=6526

like image 188
Seth Ladd Avatar answered Sep 20 '22 01:09

Seth Ladd


First add the js dependency to your pubspec.yaml :

dependencies:
  js: any

By using js-interop you can write almost the same code as in javascript.

import 'dart:html';
import 'package:js/js.dart' as js;

void main() {
  js.scoped(() {
    js.context.$(new js.Callback.once(($) {
      $('p').hide('slow', new js.Callback.once(() {
        js.context.alert("The paragraph is now hidden");
      }));
    }));
  });
}

The main differences are :

  • You have to use js.Callback.once or js.Callback.many to set your callback functions. Use js.Callback.once if your callback is call only one time.
  • Your code must be wrapped with the js.scoped. Basically, managing proxy lifetimes is here to prevent memory leak.

That said, you can simplify the above code :

import 'dart:html';
import 'package:js/js.dart' as js;

void main() {
  js.scoped(() {
    js.context.$('p').hide('slow', new js.Callback.once(() {
      window.alert("The paragraph is now hidden");
    }));
  });
}

The changes are :

  • js.context.$(new js.Callback.once(($) { isn't needed because main is equivalent to the jQuery $(function).
  • js.context.alert has been replace by window.alert : it's more efficient to directly use DART functions instead of communicate with JS.
like image 22
Alexandre Ardhuin Avatar answered Sep 24 '22 01:09

Alexandre Ardhuin