具有隔离范围和内部控制器的Angular JS指令

时间:2016-02-17 17:39:43

标签: angularjs controller directive isolate-scope

当我写作时,我还没有触及角度js,我们使用了一个带有打字稿的风格,这对我来说非常简单。现在我想写香草角js,我觉得我有点困惑。

问题:
我有一个在其隔离范围内有一些变量的指令,我基本上想要绑定到在每个<ul>内为一个click事件生成的指令。我尝试直接绑定ng-click和链接元素e.t.c上的函数。绑定点击,但似乎我做错了,因为第一种方式没有任何反应,第二种方式双向绑定变量未定义。

这里有: https://plnkr.co/edit/OOBMs8pYONLjUE9lQXla?p=preview

活性-header.html中

<div>
<h4>
Activity Name: {{activity.activity_name}}
</h4>

<h6>    
Activity Start Date: {{activity.activity_start_date}}
</h6>

<h6>        
Activity End Date: {{activity.activity_end_date}}
</h6>

<h6>
Participants: {{activity.participants}}
</h6>
</div>

活性-header.js

var app = angular.module('mainApp');

/*
app.controller('activityHeaderCtrl', ['$scope', function($scope) {
    $scope.activity='';
    $scope.msg='';
    $scope.check = function() {
            alert($scope.msg);
        };
}]);
*/

app.directive('activityHeader', function() {
    return {
        restrict: 'AE',
        templateUrl: 'activity-header.html',
        controller: ['$scope', Controller],
        scope: {
            activity:'=',
            msg:'='         
        },
        link: function($scope, $element, attrs) {
        $element.bind('click', function($scope) {
            alert($scope.msg);
        })}
    };        
    function Controller($scope) {
        $scope.check = function() {
            alert($scope.msg);
        };

    }
});

的index.html

<html ng-app="mainApp">

    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
    <script src="script-main.js"></script>
    <script src="activity-header.js"></script>

<body>

    <div ng-controller="ctrl">

        <h1>
            Major Bla bla System    
        </h1>

        <ul>        
            <li ng-repeat="x in events">                
                <div activity-header activity="x" msg="greetingsfriend" ng-click="check()"></div>
            </li>
        </ul>    

        <h6>
            Beta v.0.2
        </h6>

    </div>

</body>

</html>

脚本main.js

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

app.controller('ctrl', function ($scope) {

    //$scope.events = ["Elections", "Protest", "Martial Law", "X-mas Celebration"];
    $scope.events = [
        {"activity_name": "Elections", "activity_start_date": "31/12/2014", "activity_end_date": "31/12/2015", "participants": "1453"},
        {"activity_name": "Martial Law", "activity_start_date": "31/12/2014", "activity_end_date": "31/12/2015", "participants": "1821"},
        {"activity_name": "Protest", "activity_start_date": "31/12/2014", "activity_end_date": "31/12/2015", "participants": "1940"},
        {"activity_name": "X-mas Celebration", "activity_start_date": "31/12/2014", "activity_end_date": "31/12/2015", "participants": "2009"}
    ];

    $scope.salute = function () {
        alert('hello there');
    };

});

(顺便说一下,我使用的是Mozilla Firefox,否则我必须在node.js上托管它,以获得相同的原始政策,不知道如何将其关闭chrome / internet explorer)。

3 个答案:

答案 0 :(得分:1)

取决于您想要获得的内容。

例如,如果要在单击时绑定指令的功能,则不需要链接功能。您可以使用ng-click简单地绑定外部div上的单击。请参阅此示例:http://jsbin.com/sanova/edit?html,js,output

但是如果要在父控制器上调用函数,则需要使用指令中的属性传递对该函数的引用。请参阅此示例:http://jsbin.com/peqasu/edit?html,js,output

正如您所看到的,我在指令模板中的外部div上放置了ng-click指令。单击时,将调用指令控制器上的检查功能。在第一个示例中,只需提醒消息,在第二个示例中调用作为指令属性传递的greetFunction。

答案 1 :(得分:0)

  

有关如何处理点击的任何想法?

您的问题是您使用$scope作为点击处理函数中第一个参数的名称。该名称覆盖了链接函数的$scope参数。

    //BAD
    link: function($scope, $element, attrs) {
    $element.bind('click', function($scope) {
        alert($scope.msg);
    })}

修复你的代码:

    //GOOD
    link: function(scope, element, attrs) {
        element.on('click', function clickHandler(event) {
            console.log(scope.msg);
        });
    }

AngularJS jqLite调用点击处理程序,JQuery Event Object作为第一个参数而不是$scope

  

这是处理指令事件的正确方法吗?   为什么ng-click事件无法调用我在指令控制器中的函数?

ng-click指令绑定到父作用域中的函数。

要将点击事件绑定到指令范围内的函数,请使用element.on()。这是ng-click从浏览器获取事件的方式。查看source code

答案 2 :(得分:0)

首先,您需要了解智能组件和哑组件(指令)之间的区别。

在这里,您可以阅读一篇非常好的文章,解释与Redux的创建者Dan Abramov撰写的智能和愚蠢组件的区别:https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0

当你理解这种差异时,你可以尝试编写更多愚蠢的组件而不是更聪明的组件。这意味着您需要保留父项组件的所有逻辑并将其传递给您的哑组件。

在前面的例子中,我们只在第二个例子中这样做。实际上,在该示例中,我们将逻辑(我们的检查函数)保留在父组件中,并仅传递对它的引用。通过这种方式,活动标题组件不知道完成单击后要执行的操作。它只知道它必须调用一个函数,这个函数做的不是它的问题。

这是一个很好的方法,可以在复杂的应用程序中使用,因此您只需更改参考函数就可以以不同的方式重用组件。