控制器指令和指令控制器正确的通信方式

时间:2015-04-27 05:15:37

标签: jquery angularjs angularjs-scope angular-directive

我有一个页面,其中包含pageNavigator页面显示内容。根据用户click在相应的按钮(链接)上我正在更新页面。

我制定了以下指令:page navigator as' docNavigation'并包含在我的home html中。

现在我要求,

加载页面时

  1. 我的文档页面应该显示count我在homeController中的内容,switch最后一个案例应设置为20我在homeController中设置{ {1}}。

  2. 当用户互动时,我想更新count中的homeController以更新网页内容。

  3. 获得此功能的正确方法是什么?

    这是我的指示:

    "use strict";
    
    angular.module("docNaviDir", [])
        .directive("docNavigation", function () {
            return {
                restrict : "E",
                replace : true,
                templateUrl : '/views/directiveViews/docNavigation.html',
                link : function (scope, element, attr, controller) {
                   var count = 0;
                    element.find('a').on('click', function () {
    
                        var Id = $(this).prop('id');
                        switch(Id) {
                            case 'first':
                                count = 1; //update to `homeController`
                                break;
                            case 'prev':
                                count -= 1;  //update to `homeController`
                                break;
                            case 'next':
                                count += 1;  //update to `homeController`
                                break;
                            case 'last':
                                count = scope.totalPages; //get from `homeController`
                                break;
                        }
                    scope.$apply(function () {
                        count = count;
                    })
                    })
                }
            }
        })
    

    我的homeController:

    "用户严格&#34 ;;

    angular.module("ngTenderDocument")
        .controller('homeController', function ($scope) {
            $scope.count = 0; //pass to directive and update by user
            $scope.totalPages = 20; //pass to directive
        })
    

    我的观点:

    <doc-navigation></doc-navigation> //directive
    <h1>This is from home! Now you start to count, count is : {{count}}</h1> //count need to show the appropriate updates here.
    

    我的Navi视图:

    <nav class="navbar navbar-inverse">
        <ul class="nav navbar-nav">
            <li class="active"><a id="first" href="#">First</a></li>
            <li><a id="prev" href="#">Previous</a></li>
            <li><a id="next" href="#">Next</a></li>
            <li><a id="last" href="#">Last</a></li>
        </ul>
    </nav>
    

3 个答案:

答案 0 :(得分:1)

我将使用对象定义和范围映射,如

$scope.page = {
    totalPages: 10,
    count: 4
};

然后

app.directive("docNavigation", function () {
    return {
        restrict: "E",
        replace: true,
        //use your url
        template: '<div>' + '<a data-type="first" href="">first</a>' + '<a data-type="prev" href="">prev</a>' + '<a data-type="next" href="">next</a>' + '<a data-type="last" href="">last</a>' + '</div>',
        scope: {
            page: '='
        },
        link: function (scope, element, attr, controller) {
            element.find('a').on('click', function () {
                //using hard coded ids in a directive is dangerous as there can be other elements with the same id
                var type = angular.element(this).attr('data-type');
                switch (type) {
                    case 'first':
                        scope.page.count = 1; //update to `homeController`
                        break;
                    case 'prev':
                        scope.page.count -= 1; //update to `homeController`
                        break;
                    case 'next':
                        scope.page.count += 1; //update to `homeController`
                        break;
                    case 'last':
                        scope.page.count = scope.page.totalPages; //get from `homeController`
                        break;
                }
                scope.$apply(function () {})
            })
        }
    }
});

演示:Fiddle

答案 1 :(得分:1)

另一个答案中提供的解决方案是正确的,即您可以将变量传递给您的指令。

我想指出,虽然你正在混合香草和AngularJS。在您的指令中,您将在Angular的意识之外附加一个点击事件处理程序,这将导致稍后出现问题。因此,我建议您将指令代码更新为:

app.directive("docNavigation", function () {
    return {
        restrict: "E",
        replace: true,
        templateUrl: '/views/directiveViews/docNavigation.html',
        scope: {
            page: '='
        },
        link: function (scope, element, attr, controller) {

            scope.goToPrevious = function(){
                 scope.page.count -= 1;
            };

            scope.goToNext = function(){
                scope.page.count += 1;
            };

            scope.goToFirst = function(){
                scope.page.count = 1;
            };

            scope.goToLast = function(){
                scope.page.count = scope.page.totalPages;
            }
        }
    }
});

然后将模板更新为

<nav class="navbar navbar-inverse">
    <ul class="nav navbar-nav">
        <li class="active"><a ng-click="goToFirst()" href="#">First</a></li>
        <li><a ng-click="goToPrevious()" href="#">Previous</a></li>
        <li><a ng-click="goToNext()" href="#">Next</a></li>
        <li><a ng-click="goToLast()" href="#">Last</a></li>
    </ul>
</nav>

答案 2 :(得分:0)

使用隔离范围并从指令属性向其传递计数值。在隔离范围内,您需要提及scope: { count: '=' },,它将使用count属性中指定的控制器变量与directive计数变量进行双向绑定。

<强>标记

<doc-navigation count="count"></doc-navigation>

<强>指令

angular.module("docNaviDir", [])
    .directive("docNavigation", function () {
        return {
            restrict : "E",
            replace : true,
            scope: {
              count: '=' //specified two way binding here
            },
            templateUrl : '/views/directiveViews/docNavigation.html',
            link : function (scope, element, attr, controller) {
                element.find('a').on('click', function () {
                    var count = 0;
                    var Id = $(this).prop('id');
                    switch(Id) {
                        case 'first':
                            count = 1; //update to `homeController`
                            break;
                        case 'prev':
                            count -= 1;  //update to `homeController`
                            break;
                        case 'next':
                            count += 1;  //update to `homeController`
                            break;
                        case 'last':
                            count = scope.totalPages; //get from `homeController`
                            break;
                    }
                    scope.count = count;
                });
            }
        }
    })