markovuksanovic
markovuksanovic

Reputation: 15906

How to trigger a function inside NgComponent from outside of the component?

I have the following component

@NgComponent(selector: 'foo',
  template: '<div>foo component</div>')
class FooComponent {
  void doSomething();
}

it's used as follows:

<html>
<head></head>
<body>
  <foo ng-click="ctrl.doSomething()"></foo> // This is wrong
</body>
</html>

How do I actually execute a function inside an NgComponent?

Upvotes: 2

Views: 749

Answers (4)

grohjy
grohjy

Reputation: 2149

This question keeps bothering me and I had to test it a little bit more. In the following example a component has multiple functions and multiple build-in ng-directives. You can define which functions are related to which ng-directives through component's attributes.

html:

<!DOCTYPE html>

<html ng-app>
  <head>
    <meta charset="utf-8">
    <title>Foo</title>
    <link rel="stylesheet" href="ok_comp.css">
  </head>
  <body>
    <foo2 click="test" doubleclick="test2"></foo2>
    <foo2 click="test2"></foo2>

    <script type="application/dart" src="ok_comp.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

comp.dart:

import 'dart:html';
import 'package:angular/angular.dart';

@NgComponent(
    selector: 'foo2',
    template: '<div ng-click="cmp.ngClick()" ng-doubleclick="cmp.ngDoubleClick()">foo2</div>',
    publishAs: 'cmp'
)
class Foo2Comp extends NgAttachAware {
  @NgAttr('click')
  var strClick;
  @NgAttr('doubleclick')
  var strDoubleclick;

  var ngClick;
  var ngDoubleClick;

  Foo2Comp(){
  }

  attach(){
    ngClick = redirectFunc(strClick);
    ngDoubleClick = redirectFunc(strDoubleclick);
  }

   redirectFunc(String funcName){
    var ng;
    switch (funcName) {
      case 'test':
        ng = test;
        break;

      case 'test2':
        ng = test2;
        break;

      default:
        ng = empty;
        break;          
    }
    return ng;
  }

  empty(){
    print ("empty");
  }
  test(){
    print ("test");
  }
  test2(){
    print ("test2");
  }
}

class MyAppModule extends Module {
  MyAppModule() {
    type(Foo2Comp);
  }
}
void main() {
  ngBootstrap(module: new MyAppModule());
}

Upvotes: 0

grohjy
grohjy

Reputation: 2149

Here is a one poor solution, but if there is no other solution, then you can use this.

EDIT: I updated this solution completely. With this example one can define what event component recognizes and to what function each event is attached.

html:

<!DOCTYPE html>

<html ng-app>
  <head>
    <meta charset="utf-8">
    <title>Foo</title>
    <link rel="stylesheet" href="ok_comp.css">
  </head>
  <body>
    <foo click="test()" doubleclick="test2()"></foo>
    <foo click="test2()"></foo>

    <script type="application/dart" src="ok_comp.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

comp.dart:

import 'dart:html';
import 'package:angular/angular.dart';

@NgComponent(
 selector: 'foo',
 template: '<div>foo</div>'
)
class FooComp extends NgAttachAware {
  @NgAttr('click')
  var click;
  @NgAttr('doubleclick')
  var doubleclick;

  Element element;
  var func;

  FooComp(this.element){
  }

  attach(){
    attachFunc("click", click);
    attachFunc("doubleclick", doubleclick);
  }

  void attachFunc(String listener, String funcName){
    switch (funcName) {
      case 'test()':
        func = test;
        break;

      case 'test2()':
        func = test2;
        break;
    }

    switch (listener) {
      case 'click':
        element.onClick.listen(func);
        break;

      case 'doubleclick':
        element.onDoubleClick.listen(func);
        break;
    }
  }

  test(MouseEvent event){
    print ("test");
  }
  test2(MouseEvent event){
    print ("test2");
  }
}



class MyAppModule extends Module {
  MyAppModule() {
    type(FooComp);
  }
}
void main() {
  ngBootstrap(module: new MyAppModule());
}

Upvotes: 1

grohjy
grohjy

Reputation: 2149

You can add an event listener to component. Here is an example:

html:

<foo></foo>

comp.dart:

@NgComponent(selector: 'foo',
  template: '<div>foo component</div>')
class FooComponent {
  FooComponent(Element elem){
    elem.onClick.listen(doSomething);
  }

  void doSomething(MouseEvent event){
    print("click");
  }
}

Upvotes: 0

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657909

Good question

What I come up with (probably not exactly what you are looking for):

@NgController(
  selector: '[do-something]',
  publishAs: 'ctrl'
)
class DoSomething {

  FooComponent _foo;
  DoSomething(this._foo);

  void clickHandler(e) {
    _foo.doSomething();
  }
}

.

<foo do-something ng-click="ctrl.doSomething()"></foo>

Upvotes: 1

Related Questions