AngularJS指令两个数据绑定 - 我做错了什么?

时间:2015-02-20 01:14:19

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-service

所以我有一个双向数据绑定,我不明白它为什么不工作,它不会更新:

angular.module('core').directive('collapseNavOnClick', [
function() {
    return {
        restrict: 'A',
        scope: {
            collapseNavOnClick: '=',
            isCollapsed: '='
        },
        link: function(scope, elm, attrs) {
            console.log(scope.isCollapsed);
            console.log(scope.collapseNavOnClick);
            elm.on('click', function() {
                console.log(scope.collapseNavOnClick);
                console.log(scope.isCollapsed);
            });

        }
    };
}
]);

这是HTML:

<section data-ng-controller="HomeController" data-ng-init="init()" collapse-nav-on-click="isCollapsed" is-collapsed="isCollapsed">

我的控制器(HeaderMenu是一项服务):

angular.module('core').controller('HomeController', ['$scope','HeaderMenu',
    function($scope, HeaderMenu) {
        $scope.isCollapsed = HeaderMenu.isCollapsed;

所以问题是,当我点击&#39;并且isCollapsed已经改变,它没有在指令上更新,为什么?

&#39; isCollapsed&#39;值由控制器更改,更具体地说,有一个由ng-click触发的控制器功能,它会改变&#39; isCollapsed&#39;。

我可以在控制器中记录isCollapsed的值,看看它是否已经改变,但指令没有获得更新的值。

更多说明:

所以更多信息,我在其他地方点击了一下:

这样做会改变isCollapsed值,更具体地说,它会弹出一个菜单。

现在我要做什么,当点击body元素时,我想要隐藏该菜单,但我需要检查菜单是否已经折叠,所以我需要读取&#39; isCollapsed&#39的值;。因此,我有一个点击&#39;点击&#39;事件

所以我需要的是,在点击&#39;身体&#39;元素,读取&#39; isCollapsed&#39;的当前值并采取行动。

更新

我已将其缩小到根本问题:

$ scope.isCollapsed = HeaderMenu.isCollapsed;

该行实际上并未与HeaderMenu服务同步,我应该已经分配了整个对象而不仅仅是一个字段。完全监督这一点。

3 个答案:

答案 0 :(得分:0)

根据您的问题,某处的ng-click会触发isCollapsed更改。您想要监控该更改。

您目前正在指令中执行此操作,方法是通过以下方式侦听导致更改的点击:

elm.on('click', function() {
    console.log(scope.collapseNavOnClick);
    console.log(scope.isCollapsed);
});

运行此命令时,完全有可能ng-click尚未运行,具体取决于单击元素在html层次结构中的位置。你真正想做的是:

scope.$watch('isCollapsed', function() {
    console.log(scope.isCollapsed);
});

如果您需要注意身体点击,请在指令中执行此操作。此外,您应该使用$ scope。$ apply

$('body').on('click', function() {
    scope.$apply(function(){
        console.log(scope.collapseNavOnClick);
        console.log(scope.isCollapsed);
    });
});

答案 1 :(得分:0)

使用指令创建新范围。您可以从指令访问控制器范围,但控制器无法访问指令的范围。将范围设置为false,并在链接

中分配变量
angular.module('core').directive('collapseNavOnClick', [
function() {
    return {
        restrict: 'A',
        scope: false,
        link: function(scope, elm, attrs) {
            scope.isCollapsed = attrs['collapseNavOnClick'];
            scope.collapseNavOnClick = attrs['isCollapsed '];
            console.log(scope.isCollapsed);
            console.log(scope.collapseNavOnClick);
            elm.on('click', function() {
                console.log(scope.collapseNavOnClick);
                console.log(scope.isCollapsed);
            });

        }
    };
}
]);

答案 2 :(得分:0)

我只想更新我遇到的问题,这是一个我忽略的非常简单的问题。

在服务对象中共享变量的一个常见问题不是给变量本身,而是给出包含它的对象。

即。我的问题是:

$scope.isCollapsed = HeaderMenu.isCollapsed.

相反,我应该这样做:

$scope.headMenu = HeaderMenu;

然后在我的所有代码上执行此操作,包括指令:

$scope.headerMenu.isCollapsed = true;

我想我们很多人已经知道这一点,我们有时会忘记它!