Angular Dart:从外部操作控制器时,数据绑定不起作用,第二部分

时间:2014-07-10 13:07:14

标签: dart angular-dart

简短背景:

此示例是我的Angular Dart: Data binding doesn't work when manipulating the controller from the outside问题的一个稍微复杂的版本,已正确回答。我只在这个版本中添加了一个可切换的“show resolved comments”链接。即使我将每个变量初始化为非空值,问题仍然会发生。

实际问题的完整描述:

我有两个相互嵌套的控制器。外部控制器使用ng-switch指令显示/隐藏内部控制器。

外部控制器还包含一个复选框。如果选中此复选框,则内部控制器可见(通过上面的ng-switch指令)。此复选框按预期工作。

控制器外还有一个“开放”链接。它的onclick处理程序调用外部控制器,并且应该通过模型检查复选框。问题是即使模型被更改,视图也不会更新,除非我明确地调用scope.apply(),我不应该这样做。即使我在代码中删除了scope.apply()之前的注释,那么数据绑定在InnerController中也不起作用。

这种模式在AngularJS中完美运行,但显然不在AngularDart中。

我坚持使用这种模式或类似的东西,因为我正在将AngularDart集成到不使用数据绑定的遗留应用程序中,因此我必须从模型外部触发模型更改。

提前致谢!

<html ng-app>
<head>
    <title>Angular.dart nested controllers</title>
</head>
<body>
<a href="#" id="open">open</a>
<div outer-controller ng-switch="outerCtrl.showInnerController">
    <input type="checkbox" ng-model="outerCtrl.showInnerController">
    <div inner-controller ng-switch-when="true">
        Your name: <input ng-model="innerCtrl.yourName">
        <br>
        Hello {{innerCtrl.yourName}}!
        <div ng-switch="innerCtrl.showResolvedComments" style="text-decoration:underline; color:blue; cursor:pointer">
            <div ng-switch-when="true" ng-click="innerCtrl.showResolvedComments = false">Hide resolved comments</div>
            <div ng-switch-when="false" ng-click="innerCtrl.showResolvedComments = true">Show resolved comments</div>
        </div>
    </div>
    <div inner-controller ng-switch-when="false">
        other controller
    </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 showInnerController = false;
        Scope scope;
        OuterController(this.scope) {
            outerController = this;
        }

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

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

    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>

1 个答案:

答案 0 :(得分:1)

经过一些实验,它看起来像是角度监听指定的事件来激活ng-model,并且它看起来并不是每个变量,我认为因为在没有影响性能的情况下观察变量的每个变化都很复杂。

您可以通过模拟用户点击复选框来更改您的方法 像:

 CheckboxInputElement checkBox = querySelector("input");
            if (checkBox.checked == false) {
                checkBox.click();
            }

这可能不是更干净的方式,但它的工作原理

这里是补丁的完整代码

<html ng-app>
<head>
    <title>Angular.dart nested controllers</title>
</head>
<body>
<a href="#" id="open">open</a>
<div outer-controller ng-switch="outerCtrl.showInnerController">
    <input type="checkbox" ng-model="outerCtrl.showInnerController">
    <div inner-controller ng-switch-when="true">
        Your name: <input ng-model="innerCtrl.yourName">
        <br>
        Hello {{innerCtrl.yourName}}!
        <div ng-switch="innerCtrl.showResolvedComments" style="text-decoration:underline; color:blue; cursor:pointer">
            <div ng-switch-when="true" ng-click="innerCtrl.showResolvedComments = false">Hide resolved comments</div>
            <div ng-switch-when="false" ng-click="innerCtrl.showResolvedComments = true">Show resolved comments</div>
        </div>
    </div>
    <div inner-controller ng-switch-when="false">
        other controller
    </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 showInnerController = false;
        Scope scope;
        OuterController(this.scope) {
            outerController = this;
        }

        void showOuterController() {
            showInnerController = true;
            print("showOuterController");
            //scope.apply();
        }
    }

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

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

    main() {
        applicationFactory().addModule(new MyAppModule()).run();
        querySelector('#open').onClick.listen((Event event) {
            outerController.showOuterController();
            // Added Code
            CheckboxInputElement checkBox = querySelector("input");
            if (checkBox.checked == false) {
                checkBox.click();
            }
            // End added code
        });
    }
</script>
</body>
</html>