从儿童指令中的父指令获取属性值

时间:2014-05-02 21:18:44

标签: angularjs angularjs-directive angularjs-scope

我有两个Angular指令,一个嵌套在另一个中,如下所示。

HTML

<gss-response-group response-group-id="43" response-group-title="'Group Title'">
  <gss-response-option option-id="5" option-text="'Very Often'" option-value="5.00" options-inline="true" type="'radio'"></gss-response-option>
  <gss-response-option option-id="6" option-text="'Often'" option-value="4.00" options-inline="true" type="'radio'"></gss-response-option>
  <gss-response-option option-id="7" option-text="'Sometimes'" option-value="3.00" options-inline="true" type="'radio'"></gss-response-option>
  <gss-response-option option-id="8" option-text="'Rarely'" option-value="2.00" options-inline="true" type="'radio'"></gss-response-option>
  <gss-response-option option-id="9" option-text="'Never'" option-value="1.00" options-inline="true" type="'radio'"></gss-response-option>
</gss-response-group>

responseGroup.template.html

  <div class="gss-response-group">
    <label class="gss-response-group-title" ng-if="responseGroupTitle != null">{{responseGroupTitle}}</label>
    <placeholder></placeholder>
  </div>

responseOption.template.html

<div ng-class="{'gss-response-option': optionsInline}">
  <input class="gss-{{type}}-option" id="{{id}}" name="{{groupName}}" type="{{type}}" value="{{optionValue}}" />
  <label class="gss-option-text" for="{{id}}">{{optionText}}</label>
  <div class="gss-specifyanswer" ng-if="specify">
    <label class="gss-specifyanswer" ng-if="specifyText != null">{{specifyText}}</label>
    <textarea class="gss-specifyanswer" maxlength="5000" disabled></textarea>
  </div>
</div>

的JavaScript

'use strict';

angular.module( 'gssApp', [ 'gss.directives' ] );

angular.module( 'gssApp' )

.controller( 'gssAppController', [

    '$scope',
    '$http',
    '$rootScope',

    function ( $scope, $http, $rootScope )
    {

    }] );

var directiveModule = angular.module( 'gss.directives', [] );

directiveModule.directive( 'gssResponseGroup', function ()
{
  return {
    restrict: 'E',
    transclude: true,
    replace: true,
    scope: {
      responseGroupTitle: '=',
      responseGroupId: '='
    },
    templateUrl: 'responseGroup.template.html',
    link: function ( scope, element, attrs, ctrl, transclude )
    {
      element.find( 'placeholder' ).replaceWith( transclude() );
    },
    controller: [

        '$scope',
        '$rootScope',
        '$element',
        '$attrs',

    function ( $scope, $rootScope, $element, $attrs )
    {

    }]
  };
} );

directiveModule.directive( 'gssResponseOption', function ()
{
  return {
    restrict: 'E',    
    transclude: true,
    replace: true,
    scope: {
      responseGroupId: '=',
      optionId: '=',
      optionText: '=',
      optionValue: '=',
      type: '=',
      optionsInline: '=',
      specify: '=',
      specifyText: '='      
    },
    templateUrl: 'responseOption.template.html',
    controller: [

        '$scope',
        '$rootScope',
        '$element',
        '$attrs',

    function ( $scope, $rootScope, $element, $attrs )
    {
      // HOW DO I GET THE PARENT DIRECTIVE'S SCOPE TO USE THE
      // responseGroupId FROM IT?
      $scope.id = 'rgID' + '_' + $scope.responseGroupId + '_' + $scope.optionId;
      $scope.groupName = 'rg' + '_' + $scope.responseGroupId;
    }]
  };
} );

我希望child指令可以访问父级中的“response-group-id”字段。我该怎么做呢?我能够通过子指令要求父指令然后在子指令的“link”方法中获取它来获得值,但是到那时它已经太晚了,无法应用于子模板。

Code in Plunker

另外,如果有人能告诉我为什么CSS没有在我的Plunker项目中应用,我会很感激(尽管不是很大)。

2 个答案:

答案 0 :(得分:3)

要在指令之间共享数据,建议在父指令的控制器上定义共享数据,并从子指令的link函数访问它(参见{{3中的最后一个示例“创建通信指令”) }})。

所以你的父指令的控制器看起来像:

function ( $scope, $rootScope, $element, $attrs )
{
  this.id = $scope.responseGroupId;
}]

你的孩子指令看起来像是:

directiveModule.directive( 'gssResponseOption', function ()
{
  return {
  ...
  require: '^gssResponseGroup',
  link: function(scope, element, attrs, gssResponseGroupCtrl) {
    scope.id = 'rgID' + '_' + gssResponseGroupCtrl.id + '_' + scope.optionId;
    scope.groupName = 'rg' + '_' + gssResponseGroupCtrl.id;
  }

请注意,如果插入responseGroupId,此解决方案将会中断。如果值更改,它将不会反映在控制器id属性中,因为它仅设置一次。控制器必须定义一个始终检查id的最新值的getter方法,而不是$scope.responseGroupId属性。

答案 1 :(得分:0)

虽然我认为你做的事情比他们需要的要困难得多,但这是一个解决方案:

<gss-response-group response-group-id="43">
  <gss-response-option response-group-id="responseGroupId"></gss-response-option>
</gss-response-group>

然后在你的responseGroupOption指令中

return {
  // Other Logic...
  scope: {
    responseGroupId: '='
  }
};