【问题标题】:How to trigger a function inside NgComponent from outside of the component?如何从组件外部触发 NgComponent 内部的函数?
【发布时间】:2014-03-23 10:34:24
【问题描述】:

我有以下组件

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

用法如下:

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

如何在 NgComponent 中实际执行函数?

【问题讨论】:

  • 如果我理解正确,问题是ng-click="ctrl.doSomething()" 试图取消引用ctrl,它没有在当前范围内定义,因为ctrl 是在影子范围内定义的。
  • @MiskoHevery 是的,没错。

标签: dart angular-dart


【解决方案1】:

好问题

我想出的东西(可能不完全是你要找的东西):

@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>

【讨论】:

  • 是的,这可以完成这项工作,但关键是我不想暴露细节并添加这个额外的指令。但从技术上讲,我认为这可以完成这项工作。
  • 我试过了,它可以工作,但我也不知道在同一元素上没有控制器的解决方案。
【解决方案2】:

这是一个糟糕的解决方案,但如果没有其他解决方案,那么您可以使用它。

编辑:我完全更新了这个解决方案。通过这个示例,可以定义event 组件识别的内容以及每个事件附加到的功能。

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());
}

【讨论】:

  • 我想这会起作用,但看起来很复杂。
  • 是的,这不是一个好的解决方案,但至少可以解决一些问题。你提出的问题是一个很好的问题,我认为这种功能可能有用。它将提供更多可配置的组件,即。一个组件有更多用例。
【解决方案3】:

您可以向组件添加事件侦听器。这是一个例子:

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");
  }
}

【讨论】:

  • 他还可以将模板更改为&lt;div ng-click='ctrl.doSomething()'&gt;foo component&lt;/div&gt;。从内部看很容易,但是从外部怎么做呢?
【解决方案4】:

这个问题一直困扰着我,我不得不再测试一下。在以下示例中,组件具有多个功能和多个内置 ng 指令。您可以通过组件的属性定义哪些函数与哪些 ng 指令相关。

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());
}

【讨论】:

    猜你喜欢
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 2019-11-22
    • 2019-08-16
    • 2018-11-14
    • 1970-01-01
    相关资源
    最近更新 更多