另一个指令中的简单角度指令 - 如何将值传递给控制器​​范围

时间:2017-02-14 12:37:26

标签: javascript angularjs angularjs-directive

  

编辑:我也添加了详细信息。

我可以帮助将我的指令中选择的值传递给我的控制器$scope

我有一个非常基本的指令,我想放在另一个指令中,但该值不会传递给控制器​​范围。我得到一个"未定义"我的参数的值。

但是,当我将小指令放在视图的HTML中的任何位置,而不是在其他指令的标签内时,它就可以工作。

这是我的新指令:

(function () {
    'use strict';

    angular.module('portalDashboardApp')
      .directive('ogItemsPerPage', function () {
          return {
              restrict: 'E',
              replace: true,
              templateUrl: './tpls/ItemsPerPageTemplate.html',
              scope: {
                  perPageCountOptions: [30, 50, 100, "ALL"],
                  selectedItemsPerPage: '@'
              }
          };
      });
})();

这是模板:

<div>
    <div id="DropDownBox">
        <label for="ItemsPerpage">Items per Page: </label>
        <select ng-change="changePageCount()" ng-model="selectedItemsPerPage" id="ItemsPerpage" ng-options="perPage for perPage in perPageCountOptions"></select>
    </div>
</div>

这是我的控制器中调用的函数:

$scope.changePageCount = function () {

    if ($scope.selectedItemsPerPage === "ALL") {
        $scope.perPageCount = -1;
    }
    else {
        $scope.perPageCount = $scope.selectedItemsPerPage;
    }
    pullSocialData();
}

这是我将<og-items-per-page>指令放在另一个指令的标签内的视图:

<og-data-box heading="Tweet List" link="" uid="socialMentionsMeta" description="">
    <div class="dataStatus">
        {{dataStatus}}
        <og-loading-indicator></og-loading-indicator>
    </div>
    <og-items-per-page></og-items-per-page>
    <div class="dataContent" ng-show="dataContent" ng-mouseover="showGraphTrainingInfo()">
        <og-social-media-mentions-list></og-social-media-mentions-list>

        <div ng-show="showMorePostLoading" id="morePostLoadingContainer"><div id="morePostLoadingInner"></div></div>
    </div>
</og-data-box>

数据框指令:

(function () {
    'use strict';

    angular.module('portalDashboardApp')
        .directive('ogDataBox', function () {
            return {
                restrict: 'E',
                transclude: true,
                replace: true,
                scope: {
                    heading: '@',
                    link: '@',
                    uid: '@',
                    description: '@',
                    chartConfig: '@'
                },
                link: function (scope) {

                    scope.boxOpenCloseTitle = 'Collapse';
                    scope.iconStatus = 'upIcon';
                    scope.contentStatus = '';
                    var openCloseStatus = true;
                    var maximumSize = false;
                    scope.dataBoxUnderlayClass = '';
                    scope.dataBoxMaxMinClass = '';
                    scope.maxMinIcon = 'maximise';

                    scope.openCloseDataBox = function () {
                        if (openCloseStatus) {
                            scope.boxOpenCloseTitle = 'Expand';
                            openCloseStatus = false;
                            scope.iconStatus = 'downIcon';
                            scope.contentStatus = 'hideContent';
                        }
                        else {
                            scope.boxOpenCloseTitle = 'Collapse';
                            openCloseStatus = true;
                            scope.iconStatus = 'upIcon';
                            scope.contentStatus = '';
                        }
                    };

                    scope.maxMinDatabox = function () {

                        maximumSize = !maximumSize;

                        if (maximumSize) {
                            scope.dataBoxUnderlayClass = 'dataBoxUnderlayFullScreen';
                            scope.dataBoxMaxMinClass = 'dataBoxMaximised';
                            scope.maxMinIcon = 'minimise';
                        }
                        else {
                            scope.dataBoxUnderlayClass = '';
                            scope.dataBoxMaxMinClass = '';
                            scope.maxMinIcon = 'maximise';
                        }

                    };

                },
                templateUrl: './tpls/DataBoxTemplate.html'
            };
        });
})();

数据框模板:

<div ng-class="dataBoxUnderlayClass">
    <section class="dataBox" id="{{uid}}" ng-class="dataBoxMaxMinClass">
        <header class="dataBoxHeader">
            {{heading}}
            <img src="images/openCloseIcon.svg" title="{{boxOpenCloseTitle}}" width="15" height="15" class="openCloseBox {{iconStatus}}" ng-click="openCloseDataBox()" />
            <img ng-mouseover="infoIconStyle='dataBoxInfoContentShow'" ng-mouseleave="infoIconStyle='dataBoxInfoContentHide'" src="images/info-icon.svg" height="15" class="dataBoxInfo" />
        </header>
        <div class="dataBoxContent {{contentStatus}}">
            <div ng-class="infoIconStyle" class="dataBoxInfoContent">{{description}}</div>
            <div ng-transclude></div>
        </div>
    </section>
</div>

如果我愿意,我需要更改哪些内容以便将指令嵌套在其他指令中?

谢谢!

1 个答案:

答案 0 :(得分:0)

问题来自您的指令创建的隔离范围。

og-data-box内的html在指令范围内,无法访问控制器范围。

正如本文http://angular-tips.com/blog/2014/03/transclusion-and-scopes/中所述,如果要访问<og-data-box></og-data-box>内的控制器范围,则需要将其附加到隔离范围。

这样的事情应该可以纠正你的问题

app.directive('og-data-box', function() {
  return {
    restrict: 'EA',
    scope: {
      heading: '=',
      link: '=',
      uid: '=',
      description: '='
    },
    transclude:true,
    link: function(scope, element, attrs, ctrl, transclude) {
      transclude(scope.$parent, function(clone, scope) {
        element.append(clone);
      });
    }
  };
});

编辑: 正如评论中提到的那样,这不是最好的方法。

您应该将范围传递到og-data-box的范围,然后您可以在嵌套指令中使用它:

og-data-box (我将selectedItemsPerPage添加到范围内)

(function () {
'use strict';

angular.module('portalDashboardApp')
    .directive('ogDataBox', function () {
        return {
            restrict: 'E',
            transclude: true,
            replace: true,
            scope: {
                heading: '@',
                link: '@',
                uid: '@',
                description: '@',
                chartConfig: '@',
                selectedItemsPerPage: '@'
            },
            link: function (scope) {

                scope.boxOpenCloseTitle = 'Collapse';
                scope.iconStatus = 'upIcon';
                scope.contentStatus = '';
                var openCloseStatus = true;
                var maximumSize = false;
                scope.dataBoxUnderlayClass = '';
                scope.dataBoxMaxMinClass = '';
                scope.maxMinIcon = 'maximise';

                scope.openCloseDataBox = function () {
                    if (openCloseStatus) {
                        scope.boxOpenCloseTitle = 'Expand';
                        openCloseStatus = false;
                        scope.iconStatus = 'downIcon';
                        scope.contentStatus = 'hideContent';
                    }
                    else {
                        scope.boxOpenCloseTitle = 'Collapse';
                        openCloseStatus = true;
                        scope.iconStatus = 'upIcon';
                        scope.contentStatus = '';
                    }
                };

                scope.maxMinDatabox = function () {

                    maximumSize = !maximumSize;

                    if (maximumSize) {
                        scope.dataBoxUnderlayClass = 'dataBoxUnderlayFullScreen';
                        scope.dataBoxMaxMinClass = 'dataBoxMaximised';
                        scope.maxMinIcon = 'minimise';
                    }
                    else {
                        scope.dataBoxUnderlayClass = '';
                        scope.dataBoxMaxMinClass = '';
                        scope.maxMinIcon = 'maximise';
                    }

                };

            },
            templateUrl: './tpls/DataBoxTemplate.html'
        };
    });
})();

然后当你调用所有指令时:

<og-data-box heading="Tweet List" link="" uid="socialMentionsMeta" description=""     selected-items-per-page="selectedItemsPerPage">
    <div class="dataStatus">
        {{dataStatus}}
        <og-loading-indicator></og-loading-indicator>
    </div>
    <og-items-per-page selected-items-per-page="selectedItemsPerPage"></og-items-per-page>
    <div class="dataContent" ng-show="dataContent" ng-mouseover="showGraphTrainingInfo()">
        <og-social-media-mentions-list></og-social-media-mentions-list>

        <div ng-show="showMorePostLoading" id="morePostLoadingContainer"><div id="morePostLoadingInner"></div></div>
    </div>
</og-data-box>