问题
I have a component that performs a task, but then needs to refresh the data (a method callable from the controller).
Is it possible to access the controller methods and properties from a component?
Is it available through Scope? Parent/root scope?
(Also noticed I'm using a directive as well which would love to access the parent scope)
回答1:
I used $broadcast ... Not sure if that's the proper way to do it or not. I imagine trying to access the controller from component/directive is circular? So maybe $broadcast is what I want?
...For methods it makes sense I guess...But I do feel like I should be able to get a property from the controller. I must be doing something wrong if I can't see the parent scope...
回答2:
You have to set the visibility on the parent then you can inject the parent to the child. (I'm only on my phone and limited possibilities) AFAIK SO has a question+answer already.
回答3:
It sounds like you have one controller and one component which is a child element of the controller. In this case you can inject the controller in the component's constructor:
@NgController(...)
class MyController {
refresh() {
...
}
}
@NgComponent(...)
class MyComponent {
MyController _myController;
MyComponent(MyController this._myController);
doSomething() {
_myController.refresh();
}
}
回答4:
Components should basically be reusable and therefore shouldn't have any reference to the calling controller. Here is one solution where two separate controllers use one component to modify controller's property. I'm not sure have I used watch-function properly or is there better way to do this. Idea comes from this question and answers: AngularDart components and model binding
edit: ops, sorry: One controller and two different properties.
ang_testi.dart:
import 'package:angular/angular.dart';
import 'package:di/di.dart';
@NgComponent(
selector: 'my-component'
)
class MyComponent {
NgModel _ngModel;
Scope _scope;
MyComponent(this._ngModel, this._scope){
_scope.$watch(() => _ngModel.modelValue, (value) => onC(value));
}
onC(value){
if(value!=null) _ngModel.modelValue=value.toUpperCase();
return _ngModel.modelValue;
}
}
@NgController(
selector: '[main-test]',
publishAs: 'ctrl')
class MainTestController {
String msg;
String msg2;
Scope _scope;
MainTestController(this._scope){
_scope.$watch(() => msg, (value) => onMsgC(value));
}
onMsgC(value){
print("msg change:$value");
}
}
class MyAppModule extends Module {
MyAppModule() {
type(MainTestController);
type(MyComponent);
}
}
void main() {
ngBootstrap(module: new MyAppModule());
}
ang_testi.html:
<!DOCTYPE html>
<html ng-app>
<head>
<meta charset="utf-8">
<title>ng-model test</title>
<link rel="stylesheet" href="ang_testi.css">
</head>
<body main-test>
<my-component ng-model="ctrl.msg"></my-component>
<my-component ng-model="ctrl.msg2"></my-component>
<p><input type="text" ng-model="ctrl.msg"></p>
<p>Hello world from {{ctrl.msg}}!</p>
<p><input type="text" ng-model="ctrl.msg2"></p>
<p>Hello world from {{ctrl.msg2}}!</p>
<script src="packages/shadow_dom/shadow_dom.min.js"></script>
<script type="application/dart" src="ang_testi.dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
回答5:
I'm sorry if I'm polluting this thread.
I found a much simpler way to create a component, which can manipulate data in the calling controller. In the following example the @NgComponent transforms the string from the calling controller to uppercase and preserves a twoway binding.
The key to preserve binding is to use the variable of type: List, Map or Class (I believe also Set and Queue will work). With these types Dart uses "pointers", not values (sorry if the terms are not correct).
The correct type of variable makes also following code work (if you use for example type: String, bindings are not working): https://github.com/angular/angular.dart/issues/264
ang_testi.dart
import 'package:angular/angular.dart';
import 'package:di/di.dart';
@NgComponent(
selector: 'my-component'
)
class MyComponent {
List _test;
@NgTwoWay('test')
set test(List list){
_test=list;
}
List get test{
_test[0]=_test[0].toUpperCase();
return _test;
}
}
@NgController(
selector: '[main-test]',
publishAs: 'ctrl')
class MainTestController {
List msg=[""];
List msg2=[""];
}
class MyAppModule extends Module {
MyAppModule() {
type(MainTestController);
type(MyComponent);
}
}
void main() {
ngBootstrap(module: new MyAppModule());
}
ang_testi.html
<!DOCTYPE html>
<html ng-app>
<head>
<meta charset="utf-8">
<title>ng-model test</title>
<link rel="stylesheet" href="ang_testi.css">
</head>
<body main-test>
<my-component test="ctrl.msg"></my-component>
<my-component test="ctrl.msg2"></my-component>
<p><input type="text" ng-model="ctrl.msg[0]"></p>
<p>Hello world from {{ctrl.msg[0]}}!</p>
<p><input type="text" ng-model="ctrl.msg2[0]"></p>
<p>Hello world from {{ctrl.msg2[0]}}!</p>
<script src="packages/shadow_dom/shadow_dom.min.js"></script>
<script type="application/dart" src="ang_testi.dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
来源:https://stackoverflow.com/questions/21786048/access-controller-method-from-component-and-or-directive