AngularJS,将指令的数据更改通知给其父控制器

时间:2015-04-27 13:46:25

标签: angularjs angularjs-directive

我有一个抽象菜单的指令。需要将菜单项选择通知给其父控制器,以便它可以采取必要的操作。我可以通过多种方式实现这一目标。

  1. 将范围变量从控制器传递给指令,并观察此变量的变化。在指令中更改此变量以指示选择选项。

  2. 将一个回调方法从控制器传递给指令。在更改时从指令调用回调。

  3. 使用$ scope。$ on观察控制器中的更改,并使用范围通知指令。$ emit

  4. 我无法清楚地知道哪个选项更好。我倾向于选项3,因为它似乎更清洁,但我不确定这是否有不必要的耦合。我想听听其他人的意见,哪种解决方案有利于明确的依赖性,有利于可测试性。

    更新:

    在阅读了建议和想法后,我选择了选项2,原因如下:

    1. 通过查看关于依赖性的HTML

      非常明显
      <menu save="onSave()" filterByDate="filterByDate(date)"></menu>
      
    2. 单元测试非常明确,并告诉API(接口)指令

2 个答案:

答案 0 :(得分:1)

我个人不喜欢使用observe \ emit \ on,除非我也有。看待正在设置的其他代码并不总是显而易见的。这可能导致意大利面条代码。如果你有一个回叫,我发现直接链接更明显,更容易找到。这与声名远播的物业等结合在一起。在一天结束时,这是个人\团队品味的问题。

答案 1 :(得分:0)

我建议使用1的修改版本。但不是传递变量,而是在任何需要的地方注入服务。

该服务可能如下所示:

    yourApp.factory('SelectedMenu',
        function () {
            //set a default or just initialize it
            var menuItem = {
                id: 1,
                code:"x"
            };
            return {
                getId: function () { return menuItem.id; },
                getCode: function() { return menuItem.code;},
                setId: function(newId){menuItem.id = newId},
                setCode: function(newCode){menuItem.code=newCode;},
            };
        }
    );

在控制行为的指令中创建一个手表:

    $scope.$watch(
                        function() {
                            //should be idempotent!  can execute multiple times per $digest cycle when a change is detected
                            // (good compromise for not polluting $rootScope)
                            return SelectedMenu.getId();
                        },
                        function( newValue) {
                            //do your thing...
                        }
                    );

当您需要使用它/更新值时,您可以设置所需的代码或任何其他属性,最后设置id以触发更新。

SelectedMenu.setId(someones.id);

这是我遇到的最干净的解决方案。如果您愿意,如果数据对象更复杂,您可以使用其他服务抽象使用更多。