How to make two-way data binding between service a

2019-08-31 01:48发布

问题:

I have a service and I have been trying to make a two-way binding to one of the service's properties within controller. Below is a code for three different approaches. The first uses $watch(), the second uses getter/setter and the third uses attribute with @NgTwoWay-binding.

I think the third one is the cleanest solution, but is it possible to write the code without the wrapper controller (test-ctrl)?

Is there a better way to do the binding?

ang.dart

import 'package:angular/angular.dart';

@NgController(selector: '[my-ctrl]', publishAs: 'ctrl')
class MyCtrlController {
  String strMsg;
  var serv;

  MyCtrlController(MyService myS, Scope _scope) {
    _scope.$watch(() => myS.message, (value) => strMsg = value);
    _scope.$watch(() => strMsg, (value) => myS.message = value);
  }
}

@NgController(selector: '[my-ctrl2]', publishAs: 'ctrl')
class MyCtrl2Controller {
  String _strMsg2;
  set strMsg2(String s) {
    _strMsg2 = s;
    serv.message = s;
  }
  String get strMsg2 {
    _strMsg2 = serv.message;
    return _strMsg2;
  }

  var serv;

  MyCtrl2Controller(MyService myS) {
    serv = myS;
    strMsg2 = myS.message;
  }
}

@NgController(selector: '[my-ctrl3]', publishAs: 'ctrl')
class MyCtrl3Controller {
  @NgTwoWay('message3')
  String message3;
}

@NgController(selector: '[test-ctrl]', publishAs: 'testctrl')
class TestCtrlController {
  var serv;

  TestCtrlController(MyService myS) {
    serv=myS;
  }
}


class MyService {
  String message = 'blue';
}

class MyAppModule extends Module {
  MyAppModule() {
    type(MyCtrlController);
    type(MyCtrl2Controller);
    type(MyCtrl3Controller);
    type(TestCtrlController);
    type(MyService);
  }
}

void main() {
  ngBootstrap(module: new MyAppModule());
}

ang.html

<!DOCTYPE html>

<html ng-app>
  <head>
    <meta charset="utf-8">
    <title>ng-model test</title>
    <link rel="stylesheet" href="ang.css">
  </head>
  <body>
    <div my-ctrl>
      <p>controller1: <input type="text" ng-model="ctrl.strMsg"></p>
      <p>Message1 is {{ctrl.strMsg}}</p>
    </div>
    <div my-ctrl2>
      <p>controller2: <input type="text" ng-model="ctrl.strMsg2"></p>
      <p>Message2 is {{ctrl.strMsg2}}</p>
    </div>
    <div test-ctrl>
      <div my-ctrl3 message3="testctrl.serv.message">
        <p>controller3: <input type="text" ng-model="ctrl.message3"></p>
        <p>Message3 is {{ctrl.message3}}</p>
      </div>
    </div>

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

回答1:

IMHO the best way is a strip-down version of your second variation:

@NgController(selector: '[my-ctrl2]', publishAs: 'ctrl')
class MyCtrl2Controller {

  var service;

  MyCtrl2Controller(MyService this.service) {
  }

  set strMsg2(String s) {
    service.message = s;
  }

  String get strMsg2 {
    return service.message;
  }

}

Hope it helps ;-)