首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >来自其他控制器的指令控制器中的调用方法

来自其他控制器的指令控制器中的调用方法
EN

Stack Overflow用户
提问于 2013-02-15 04:29:16
回答 4查看 100.7K关注 0票数 118

我有一个拥有自己的控制器的指令。请参见以下代码:

代码语言:javascript
复制
var popdown = angular.module('xModules',[]);

popdown.directive('popdown', function () {
    var PopdownController = function ($scope) {
        this.scope = $scope;
    }

    PopdownController.prototype = {
        show:function (message, type) {
            this.scope.message = message;
            this.scope.type = type;
        },

        hide:function () {
            this.scope.message = '';
            this.scope.type = '';
        }
    }

    var linkFn = function (scope, lElement, attrs, controller) {

    };

    return {
        controller: PopdownController,
        link: linkFn,
        replace: true,
        templateUrl: './partials/modules/popdown.html'
    }

});

这是一个错误/通知/警告的通知系统。我想要做的是从另一个控制器(不是指令控制器)调用这个控制器上的函数show。当我这样做的时候,我还希望我的链接函数检测到一些属性发生了变化,并执行一些动画。

下面是一些代码来举例说明我所要求的:

代码语言:javascript
复制
var app = angular.module('app', ['RestService']);

app.controller('IndexController', function($scope, RestService) {
    var result = RestService.query();

    if(result.error) {
        popdown.notify(error.message, 'error');
    }
});

因此,当在popdown指令控制器上调用show时,链接函数也应该被触发并执行动画。我怎样才能做到这一点呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-02-15 05:46:58

这是一个有趣的问题,我开始思考如何实现这样的东西。

我想到了this (fiddle)

基本上,我没有尝试从控制器调用指令,而是创建了一个模块来容纳所有的弹出逻辑:

代码语言:javascript
复制
var PopdownModule = angular.module('Popdown', []);

我在模块中放入了两样东西,一个是可以在任何地方注入的API的factory,另一个是定义实际popdown元素行为的directive

工厂只定义了几个函数successerror,并跟踪了几个变量:

代码语言:javascript
复制
PopdownModule.factory('PopdownAPI', function() {
    return {
        status: null,
        message: null,
        success: function(msg) {
            this.status = 'success';
            this.message = msg;
        },
        error: function(msg) {
            this.status = 'error';
            this.message = msg;
        },
        clear: function() {
            this.status = null;
            this.message = null;
        }
    }
});

该指令将API注入到其控制器中,并监视api的更改(为方便起见,我使用引导css ):

代码语言:javascript
复制
PopdownModule.directive('popdown', function() {
    return {
        restrict: 'E',
        scope: {},
        replace: true,
        controller: function($scope, PopdownAPI) {
            $scope.show = false;
            $scope.api = PopdownAPI;

            $scope.$watch('api.status', toggledisplay)
            $scope.$watch('api.message', toggledisplay)

            $scope.hide = function() {
                $scope.show = false;
                $scope.api.clear();
            };

            function toggledisplay() {
                $scope.show = !!($scope.api.status && $scope.api.message);               
            }
        },
        template: '<div class="alert alert-{{api.status}}" ng-show="show">' +
                  '  <button type="button" class="close" ng-click="hide()">&times;</button>' +
                  '  {{api.message}}' +
                  '</div>'
    }
})

然后我定义了一个依赖于Popdownapp模块

代码语言:javascript
复制
var app = angular.module('app', ['Popdown']);

app.controller('main', function($scope, PopdownAPI) {
    $scope.success = function(msg) { PopdownAPI.success(msg); }
    $scope.error   = function(msg) { PopdownAPI.error(msg); }
});

HTML看起来像这样:

代码语言:javascript
复制
<html ng-app="app">
    <body ng-controller="main">
        <popdown></popdown>
        <a class="btn" ng-click="success('I am a success!')">Succeed</a>
        <a class="btn" ng-click="error('Alas, I am a failure!')">Fail</a>
    </body>
</html>

我不确定它是否完全理想,但它似乎是一个合理的方式来建立一个全球式的popdown指令的通信。

同样,作为参考,请参阅the fiddle

票数 167
EN

Stack Overflow用户

发布于 2013-02-28 13:26:16

您还可以使用事件来触发Popdown。

基于satchmorun的解决方案的Here's a fiddle。它省去了PopdownAPI和顶级控制器,取而代之的是作用域链中$broadcast的“成功”和“错误”事件:

代码语言:javascript
复制
$scope.success = function(msg) { $scope.$broadcast('success', msg); };
$scope.error   = function(msg) { $scope.$broadcast('error', msg); };

然后,Popdown模块为这些事件注册处理程序函数,例如:

代码语言:javascript
复制
$scope.$on('success', function(event, msg) {
    $scope.status = 'success';
    $scope.message = msg;
    $scope.toggleDisplay();
});

这至少是可行的,在我看来是一个很好的解耦解决方案。如果出于某种原因,这被认为是糟糕的实践,我会让其他人加入进来。

票数 27
EN

Stack Overflow用户

发布于 2013-09-04 21:20:14

您还可以向父作用域公开指令的控制器,就像具有name属性的ngForm一样:http://docs.angularjs.org/api/ng.directive:ngForm

在这里你可以找到一个非常基本的例子如何实现http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview

在本例中,我使用带有$clear方法的专用控制器的myDirective (这是一种非常简单的公共指令应用程序接口)。我可以将此控制器发布到父作用域,并在指令外部使用call this方法。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14883476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档