我定义了一个angular.dart组件,如下所示:
@NgComponent( selector: 'dartcomp',templateUrl: 'dartComp.html',publishAs: 'ctrl',map: const { 'val' : '@val' } ) class DartComp { String val; calc(a,b) =>a+b; }
HTML中的用法是:
<dartcomp id="dc"></dartcomp>
如何从主dart访问angular.dart组件的属性val或方法calc()
对组件的调用就像
querySelector("#dc").val = "Frank";
扔:
类’UnknownElement’没有实例setter’val =’.
NoSuchMethodError : method not found: 'val=' Receiver: Instance of 'UnknownElement' Arguments: ["Frank"]
这个错误是什么?
访问类属性等属性在Polymer中有效,但在Angular.Dart中无效.
您必须使用Elements默认方法.attributes [‘attrName’] = value
您必须使用Elements默认方法.attributes [‘attrName’] = value
// this doesn't work with Angular // querySelector("#dc").attributes['val'] = "Frank"; // I found an AngularDart function that may help but it's comment says this is for debugging only // this example calls the method 'add' on MyComponent var mc = ngProbe(dom.querySelector('my-component')).directives.firstWhere((d) => d is MyComponent); mc.add('someValue');
也许有一种更好的方法我不知道,但这种方式应该无论如何都可以.
示例也可在此处获得:GitHub BWU-Dart Playground
这是我想出的最好的主意.
也许AngularDart创作者中的某个人知道更好的解决方案.
(我也找不到AngularJS的直接解决方案)
EventBus
/** * Derived from https://github.com/marcojakob/dart-event-bus */ library eventbus; import "dart:async"; import "dart:html"; import "package:logging/logging.dart"; /** * [EventBus] is a central event hub. * In addition it automatically updates the page navigation history ([History] * by calling [window.pushState] for fired events which indicate,that they * are supposed to update the [History] and refiring events which led to * [window.pushState] in the case of a [window.onPopState] event. */ class EventBus extends Object { final _logger = new Logger("EventBusModel"); /** * A [StreamController] is maintained for each event type. */ Map<EventType,StreamController> streamControllers = new Map<EventType,StreamController>(); bool isSync = true; /** * Constructs an [EventBus] and allows to specify if the events should be * send synchronIoUsly or asynchronIoUsly by setting [isSync]. */ EventBus({this.isSync : false}); /** * [on] allows to access an stream for the specified [eventType]. */ Stream/*<T>*/ on(EventType/*<T>*/ eventType) { _logger.finest('on'); return streamControllers.putIfAbsent(eventType,() { return new StreamController.broadcast(sync: isSync); } ).stream; } /** * [fire] broadcasts an event of a type [eventType] to all subscribers. */ void fire(EventType/*<T>*/ eventType,/*<T>*/ data) { _logger.finest('event fired: ${eventType.name}'); if (data != null && !eventType.isTypeT(data)) { throw new ArgumentError('Provided data is not of same type as T of EventType.'); } var controller = streamControllers[eventType]; if (controller != null) { controller.add(data); } } } /** * Type class used to publish events with an [EventBus]. * [T] is the type of data that is provided when an event is fired. */ class EventType<T> { String name; /** * Constructor with an optional [name] for logging purposes. */ EventType(this.name); /** * Returns true if the provided data is of type [T]. * * This method is needed to provide type safety to the [EventBus] as long as * Dart does not support generic types for methods. */ bool isTypeT(data) => data is T; }
带有MyComponent和main()的index.dart
library main; import 'dart:html' as dom; import 'dart:async'; import 'package:angular/angular.dart'; import 'package:di/di.dart'; import 'event_bus.dart'; class Item { String name; Item(this.name); } @NgComponent( selector: 'my-component',applyAuthorStyles: true,template: '''<div ng-repeat="value in ctrl.values"><span>{{value.name}}</span> - <content><content></div>''' ) class MyComponent { List<Item> values = [new Item('1'),new Item('2'),new Item('3'),new Item('4')]; void add(String value) { values.add(new Item(value)); } EventBus _eb; MyComponent(this._eb) { print('MyComponent'); _eb.on(Events.someEvent).listen((e) => add(e)); _eb.on(Events.someEventWithData).listen((SomeEventData ed) { print('Event received from ${ed.senderId}'); ed.respond(this); }); } } typedef MyComponentEventResponse (MyComponent component); class SomeEventData { SomeEventData(this.respond,this.someOtherData,[this.senderId]); MyComponentEventResponse respond; var someOtherData; String senderId; } class Events { static final EventType<String> someEvent = new EventType<String>("someEvent"); static final EventType<SomeEventData> someEventWithData = new EventType<SomeEventData>("someEventWithData"); } class MyAppModule extends Module { MyAppModule() { type(MyComponent); value(EventBus,new EventBus()); } } void main() { Injector inj = ngBootstrap(module: new MyAppModule()); EventBus eb = inj.get(EventBus); eb.fire(Events.someEvent,"17"); new Timer(new Duration(milliseconds: 1000),() => eb.fire(Events.someEvent,"33")); new Timer(new Duration(milliseconds: 2000),() => eb.fire(Events.someEventWithData,new SomeEventData(respond,'blabla','main105'))); } void respond(MyComponent c) { dom.window.alert('Demonstrate access to event receiver: Name of 2nd item: ${c.values[1].name}'); }
的index.html
<!DOCTYPE html> <html ng-app> <head> <Meta charset="utf-8"> </head> <body> <h3>Repeat</h3> <my-component> <div>some provided content to repeat</div> </my-component> <script type="application/dart" src="index.dart"></script> <script src="packages/browser/dart.js"></script> </body> </html>