如何调用从指令局部纳克点击? [英] How to invoke ng-click from a directive partial?

查看:161
本文介绍了如何调用从指令局部纳克点击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有本地范围,其中部分含有NG-点击指令。

I have a directive that has a local scope where a partial contains ng-click.

小提琴有: http://jsfiddle.net/stephanedeluca/QRZFs/13/

可惜的是,因为我感动我的code的指令,NG-点击已经不火。

Unfortunatelly, since I moved my code to the directive, ng-click does not fire anymore.

的控制器和指令是如下:

The controller and the directive is as follows:

var app = angular.module('myApp', ['ngSanitize']);

app.directive('plantStages', function ($compile) {
    return {
        restrict: 'E',
        transclude: true,
        template: '<figure class="cornStages">\
                        <p ng-transclude style="color: skyblue"></p>\
                        <hr/>\
                        <p ng-bind-html="title"></p>\
                        <p ng-bind-html="subtitle">{{subtitle}}</p>\
                        <ul>\
                            <li ng-repeat="stage in stages" ng-click="changePage(stage)">{{stage}}</li>\
                        </ul>\
                    </figure>',
        scope: {
            stages:"=",
            title:'@'
        },
        link: function (scope, element, attrs, ctrl, transclude) {
            if (!attrs.title) scope.title = "Default title";
        }
    };
});

app.controller('myCtrl', function ($scope, $location, $http) {
    $scope.stages = ['floraison', 'montaison'];
    $scope.changePage = function (page) {
        var url = "corn.page.html#/"+page;
        console.log("Change page "+page+" with url "+url);
        alert("about to change page as follows: document.location.href = "+url);
    };

});

调用它是如下的HTML:

The html that invokes it is as follows:

<div ng-controller="myCtrl">
    Stages, 
    <p ng-repeat="stage in stages">{{stage}}</p>
    <hr/>
    Plant stages
    <plant-stages 
        title="<b>Exploration<br/>du cycle</b>"
        subtitle="<em>This is a<br/>sub title</em>"
        stages="stages"
    >
        Inner<br/>directive
    </plant-stages>
</div>

任何想法?

推荐答案

您无法访问 changePage()从指令控制器的范围界定直接,因为你的指令有孤立的范围。但是,仍然有几种方法可以做到这一点:

You can't access changePage() defined in controller's scope from directive directly, since your directive has isolated scope. However, there are still several ways to do it:

选项1:

选项1是最简单的选择。然而,它很像一个解决办法,我不推荐广泛使用。您可以从通过元素让你的控制器的范围链接功能和调用 changePage 有:

Option 1 is the most simple option. However it is much like a workaround and I don't recommend to use it widely. You can get your controller's scope from element passed to link function and invoke changePage there:

link: function (scope, element, attrs, ctrl, transclude) {
    if (!attrs.title) scope.title = "Default title";
    scope.changePage = element.scope().changePage; // <= Get parent scope from element, it will have changePage()
}

选项2:

如果您还没有涉及在外部控制器确定的范围(如你的例子)的任何逻辑,你可以定义内部控制你的指令并执行它有:

If you don't have any logic that involves scope defined in the outer controller (as in your example), you can define inner controller for your directive and perform it there:

app.directive('plantStages', function ($compile) {
    return {
       ...
       controller: ['$scope', function($scope) {
           $scope.changePage = function(page) {
               var url = "corn.page.html#/"+page;
               console.log("Change page "+page+" with url "+url);
               alert("about to change page as follows: document.location.href = "+url);
           }
       }]
    };
});

选项3:

如果你想要做定义重用逻辑changePage()在不同的指令和控制器,做到这一点的最好办法是将逻辑移动到一些服务可能注入两个控制器和指令:

If you want do reuse logic defined in changePage() in different directives and controllers, the best way to do it is to move the logic to some service that may be injected to both controller and directive:

app.service('changePageService', function() {
    this.changePage = function(page) {
        var url = "corn.page.html#/"+page;
        console.log("Change page "+page+" with url "+url);
        alert("about to change page as follows: document.location.href = "+url);
    }
});

app.controller('myCtrl', function ($scope, $location, $http, changePageService) {
    ...
    changePageService.changePage('page');
    ...
});

app.directive('plantStages', function ($compile) {
    ...
    controller: ['$scope', 'changePageService', function($scope, changePageService) {
        $scope.changePage = changePageService.changePage;
    }]
    ...
});

选项4:

您可以通过一张code像 changePage(页)作为指令和内部指令定义与'和; 这将创建在外部控制器的范围与传递给函数的参数执行的功能。例如:

You can pass piece of code like changePage(page) as value of some attribute of the directive and inside directive define scope property with '&' that will create a function that will be executed in the outer controller's scope with arguments passed to that function. Example:

的JavaScript

app.directive('plantStages', function ($compile) {
    return {
        restrict: 'E',
        transclude: true,
        template: '<figure class="cornStages">\
                        <p ng-transclude style="color: skyblue"></p>\
                        <hr/>\
                        <p ng-bind-html="title"></p>\
                        <p ng-bind-html="subtitle"></p>\
                        <ul>\
                            <li ng-repeat="stage in stages" ng-click="changePage({page: stage})">{{stage}}</li>\
                        </ul>\
                    </figure>',
        scope: {
            stages:"=",
            title:'@',
            changePage:'&'
        },
        link: function (scope, element, attrs, ctrl, transclude) {
            if (!attrs.title) scope.title = "Default title";
        }
    };
});

HTML

<div ng-controller="myCtrl">
    Stages, 
    <p ng-repeat="stage in stages">{{stage}}</p>
    <hr/>
    Plant stages
    <plant-stages 
        title="<b>Exploration<br/>du cycle</b>"
        subtitle="<em>This is a<br/>sub title</em>"
        stages="stages"
        change-page="changePage(page)"
    >
        Inner<br/>directive
    </plant-stages>

Plunker: http://plnkr.co/edit/s4CFI3wxs0SOmZVhUkC4?p=$p$pview

这篇关于如何调用从指令局部纳克点击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆