父指令控制器不可用?

时间:2013-07-13 23:03:51

标签: angularjs angularjs-directive

我有一个名为<popup>的指令,其中包含许多<popup-link> - 指令。单击<popup-link>时,应通过在其控制器上调用函数<popup>来关闭父close()指令。

出于某种原因,我无法获得<popup>的控制器实例,因为它没有正确地注入<popup-link>的链接功能

我得到以下错误并检查对象产生 instantiate.c

  

对象[object Object]没有方法'close'

我做错了什么?

directive('popup', function () {
    return {
        restrict: 'EA',
        replace: true,
        transclude: true,
        template: '<div id="{{ popupId }}" class="navigatorPopup" ng-transclude></div>',
        controller: function ($scope) {
            $scope.close = function () {
                //close popup
            };
        },
        link: function (scope, element, attr) {
            //
        }
    }
}).
directive('popupLink', function () {
    return {
        restrict: 'EA',
        require: '^popup',
        template: '<h3 ng-bind="title"></h3>',
        replace: true,
        scope: {
            title: '@',
            ngClick: '&'
        },
        link: function (scope, element, attr, popupCtrl) {
            scope.popupCtrl = popupCtrl;
            element.bind('click', 
                function () {
                    scope.popupCtrl.close();
                    scope.ngClick();
                }
            );
        }
    }
});

和HTML

<popup name="menuNavigator">
   <popup-link ng-repeat="category in getCategories()" title="{{ category.Title }}" ng-click="navigateMenu($index)"></popup-link>
</popup>

谢谢!

2 个答案:

答案 0 :(得分:2)

子控制器需要父控制器的实例。将父控制器的“公共”组件视为公共。

$scope.close = function(){..}更改为this.close = function(){..}

此外,与您的子链接功能一样,将popupCtrl显式设置为本地范围并非必要。您可以使用以下命令直接访问父函数:

popupCtrl.close()

除非您更喜欢这种命名惯例......

DEMO

答案 1 :(得分:1)

您没有在点击处理程序中包装scope.$apply方法:

element.bind('click', 
    function () {
        scope.$apply(function(){
            scope.popupCtrl.close();
            scope.ngClick();
        });
    }
);

您需要使用范围包装任何在AngularJS'$apply/$digest loop之外发生的代码。$ apply方法,以便Angularjs知道发生了更改。

Editted:

抱歉,我误解了问题。

发生这种情况的原因是你将函数放在scope属性而不是控制器上:

controller: function ($scope) {
    $scope.close = function () {
        //close popup
    };
},

应该是:

controller: function ($scope) {
    this.close = function () {
        //close popup
    };
},