Angular Dart: Data binding doesn't work when manipulating the controller from the outside

Issue

I have two controllers nested into each other. The outer controller shows/hides the inner controller by using an ng-switch directive.

The outer controller also contains a checkbox. If this checkbox gets checked then the inner controller is made visible (via the above ng-switch directive). This checkbox works as intended.

There’s also an “open” link outside the controllers. Its onclick handler calls into the outer controller and is supposed to check the checkbox via the model. The problem is that even though the model gets changed, the view doesn’t get updated.

This pattern has worked flawlessly in AngularJS but apparently doesn’t in AngularDart. I’m assuming that Dart zones are the culprit (of which I’m completely clueless about at this point).

I insist to this pattern or something similar because I’m in the process of integrating AngularDart into a legacy application that doesn’t use data binding so I have to trigger model changes from outside the models.

Relying on your ultimate wisdom, thanks in advance!

<html ng-app>
<head>
    <title>Angular.dart nested controllers</title>
</head>
<body>
<a href="#" id="open">open</a>
<div outer-controller ng-switch="outerCtrl.shouldShowInnerController">
    <input type="checkbox" ng-model="outerCtrl.shouldShowInnerController">
    <div inner-controller ng-switch-when="true">
        Your name: <input ng-model="innerCtrl.yourName">
        <br>
        Hello {{innerCtrl.yourName}}!
    </div>
</div>
<script type="application/dart">
    import "dart:html";
    import 'package:angular/angular.dart';
    import 'package:angular/application_factory.dart';

    OuterController outerController;
    @Controller(selector:'[outer-controller]', publishAs:'outerCtrl')
    class OuterController {
        bool shouldShowInnerController;
        static Scope scope;
        OuterController(Scope _scope) {
            scope = _scope;
            outerController = this;
        }

        void showOuterController() {
            shouldShowInnerController = true;
            scope.apply();
        }
    }

    @Controller(selector:'[inner-controller]', publishAs:'innerCtrl')
    class InnerController {
        String yourName = 'defaultName';
    }

    class MyAppModule extends Module {
        MyAppModule() {
            type(InnerController);
            type(OuterController);
        }
    }

    main() {
        applicationFactory().addModule(new MyAppModule()).run();
        querySelector('#open').onClick.listen((Event event) {
            outerController.showOuterController();
        });
    }
</script>
</body>
</html>

Solution

Works with Dart 1.5.1 and AngularDart 0.12.0

I have only initialized the shouldShowInnerController boolean

<!DOCTYPE html>

<html ng-app>
<head>
    <title>Angular.dart nested controllers</title>
</head>
<body>
<a href="#" id="open">open</a>
<div outer-controller ng-switch="outerCtrl.shouldShowInnerController">
    <input type="checkbox" ng-model="outerCtrl.shouldShowInnerController">
    <div inner-controller ng-switch-when="true">
        Your name: <input ng-model="innerCtrl.yourName">
        <br>
        Hello {{innerCtrl.yourName}}!
    </div>
</div>
<script type="application/dart">
    import "dart:html";
    import 'package:angular/angular.dart';
    import 'package:angular/application_factory.dart';

    OuterController outerController;
    @Controller(selector:'[outer-controller]', publishAs:'outerCtrl')
    class OuterController {
        bool shouldShowInnerController = false;
        static Scope scope;
        OuterController(Scope _scope) {
            scope = _scope;
            outerController = this;
        }

        void showOuterController() {
            shouldShowInnerController = !shouldShowInnerController;
            scope.apply();
        }
    }

    @Controller(selector:'[inner-controller]', publishAs:'innerCtrl')
    class InnerController {
        String yourName = 'defaultName';
    }

    class MyAppModule extends Module {
        MyAppModule() {
            type(InnerController);
            type(OuterController);
        }
    }

    main() {
        applicationFactory().addModule(new MyAppModule()).run();
        querySelector('#open').onClick.listen((Event event) {
            outerController.showOuterController();
        });
    }
</script>
</body>
</html>

Answered By – FinistSeb

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *