AngularJS:自定义指令中的双向数据绑定不起作用

时间:2014-06-02 10:58:34

标签: javascript angularjs angularjs-directive

我在尝试理解为什么双向数据绑定在我的自定义指令中工作时遇到了问题?

代码:

指令代码:

.directive('invoiceFilter', function () {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: '_invoice-filter.tpl.html',
        scope: {
            selectedItem: '=',
            selectedItemChange: '&'
        },
        link: function(scope) {

            scope.items = {
                all: 'Show all invoices',
                draft: 'Show drafts only',
                open: 'Show open invoices',
                paid: 'Show paid invoices'
            };

            scope.raiseSelectedItemChange = function (key) {


                alert('Selected item in directive: ' + key + " (which seems to work!)");

                scope.selectedItem = key;
                scope.selectedItemChange();

            };

        }
    };
});

指令模板

<div class="btn-group dropdown">
    <button class="btn dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
        {{ items[selectedItem || 'open' ] }}
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
        <li ng-repeat="(key, value) in items">
            <a href="javascript:void(0)" ng-click="raiseSelectedItemChange(key)">{{ value }}</a>
        </li>
    </ul>
</div>

正如您所看到的,我只是在范围内(在链接功能中)添加了一些数据,并依赖于ng-repeat和ng-click的行为来引发事件/选择项目时的回调。警报正确显示所选项目。

但是当我开始使用这样的指令时:

HTML

  <body ng-controller="MainController">
    <h1>Hello Plunker!</h1>
    <invoice-filter selected-item="filter" selected-item-change="filterChange()"></invoice-filter>
  </body>

控制器

    .controller('MainController', function($scope) {

        $scope.filter = "all";

        $scope.filterChange = function() {

          alert("Selected item in controller: " + $scope.filter + " (does not work, databinding problem???)");

        };

    })

$ scope.filter值永远不会使用我在指令中选择的项目进行更新,即使我指定了&#39; =&#39;在我理解的指令范围应该启用双向数据绑定,对吗?

我在这里缺少什么?

Plunk playground

此处有一个plunkr,其中包含上述设置,因此您可以验证它无效:o /

感谢任何可以提供帮助的人!

2 个答案:

答案 0 :(得分:9)

双向绑定有效,但会在下一个周期发生。这就是为什么当你再次重现它时,会显示最后一个循环的值。这是因为AngularJS没有机会在您设置值的行和调用回调的行之间运行其数据绑定。从这个意义上说,JavaScript不允许干预yet

scope.selectedItemChange();更改为$timeout(scope.selectedItemChange);是一个简单的解决方法(不要忘记注入$timeout),强制在下一个周期调用回调。

答案 1 :(得分:0)

我已经实现了类似的东西,并解决了稍微缩短的版本:

只需添加

  

范围$手表();

之后

  

scope.selectedItem = key;

Angular将自行决定如何以及如何做。