AngularJS:如何从控制器中的自定义指令获取模型?

时间:2015-06-23 08:45:56

标签: angularjs

我尝试在自定义指令中添加要在控制器中访问的动态模型:

我的观点是这样的:

<form ng-submit="updateConfigData()" novalidate class="form-horizontal" name="questionnaires">
    <accordion close-others="true">

                    <!--Show segment questions-->
                    <accordion-group ng-repeat="(key, question) in segment.questions" id="q_{{question.q_id}}"> 
                        <accordion-heading>{{question.q_title}}</accordion-heading>
                        <div class="panel-body">
                            <custom-question qdata="question"></custom-question>
                        </div>
                    </accordion-group>

                </accordion>
</form>

我的自定义指令是这样的:

ModuleConfigQuestions.directive('customQuestion',function($compile,$sce){
  return{
    restrict:'E',
    scope: {qdata: '='},
    require: '?ngModel', // get a hold of NgModelController
    link:function(scope, element, attribute,ngModel){
      if(!ngModel) return; // do nothing if no ng-model

      var q_data = scope.qdata;

      var arr_keys = [];
      var arr_values = [];
      /*
      answers: {13: "Yes",14: "No"}
      Covert answers into separate array of
      */
      for (var key in q_data.answers) {
        if (q_data.answers.hasOwnProperty(key)) {
            arr_values.push(q_data.answers[key]);
            arr_keys.push(key);
        }
      }  

      var el = angular.element('<div>');;
      /*Make template for BOOL Type question*/
      switch( q_data.q_type ){

        case ANSWER_TYPE_BOOL :
          el.append(arr_values[0]+'&nbsp;<input type="radio" name="'+q_data.q_id+'" ng-model="formdata['+q_data.q_id+']" value="'+arr_keys[0]+'" />&nbsp;&nbsp;');
          el.append(arr_values[1]+'&nbsp;<input type="radio" name="'+q_data.q_id+'" ng-model="formdata['+q_data.q_id+']" value="'+arr_keys[1]+'" />');
        break;

      }
      $compile(el)(scope);
      element.append(el);
      // Specify how UI should be updated
      /*ngModel.$render = function() {
        element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));

      };*/

    }
  };
});

我的控制器是这样的:

ModuleConfigQuestions.controller('ctrlListQuestionnaires',function ($location,$scope,$http,$rootScope,$cookies,ServiceCheckAuth,ServiceConfigData){
    /*First check patient is logged in*/
    if( !ServiceCheckAuth.isPatientLoggedIn() ){ 
        $location.url('/login'); 
        return;
    }
    /*Set rootScope values*/
    $rootScope.root = {
        html_title:HTML_TITLE_PATIENT_QUESTIONNAIRES,
        loggedin:true,
        activeQeuestionaires:'active'
    };

    $scope.formdata = {};

    ServiceConfigData.getConfigData($scope,SECTION_BASIC_QUES);
    $scope.updateConfigData = function(){
        console.log( $scope.formdata );
    }

});     

正如您在控制器中看到的那样,我假设在提交表单时要将所有模型值附加到formdata对象中。

但这不应该正常工作,那里有谁可以指出我错过了哪些基本的东西?

注意:我已经阅读了有关使用ngModelController的信息,但无法确定应该如何应用它。

1 个答案:

答案 0 :(得分:0)

// Code goes here


var ModuleConfigQuestions = angular.module('ModuleConfigQuestions',
	[	
		'ngRoute',
    'ngCookies',
    'ngSanitize',
    'ui.bootstrap'
	]
	);
	
ModuleConfigQuestions.directive('customQuestion',function($compile,$sce){
  return{
    restrict:'E',
    scope: {qdata: '='},
    link:function(scope, element, attribute){
      var q_data = scope.qdata;
      var arr_keys = [];
      var arr_values = [];
      
      /*
      answers: {13: "Yes",14: "No"}
      Covert answers into separate array of
      */
      for (var key in q_data.answers) {
        if (q_data.answers.hasOwnProperty(key)) {
            arr_values.push(q_data.answers[key]);
            arr_keys.push(key);
        }
      }  

      var el = angular.element('<div>');
      /*Make template for BOOL Type question*/
      switch( q_data.q_type ){

        case 'bool' :
          el.append(arr_values[0]+'&nbsp;<input type="radio" name="'+q_data.q_id+'" ng-model="$parent.formdata['+q_data.q_id+']" value="'+arr_keys[0]+'" />&nbsp;&nbsp;');
          el.append(arr_values[1]+'&nbsp;<input type="radio" name="'+q_data.q_id+'" ng-model="$parent.formdata['+q_data.q_id+']" value="'+arr_keys[1]+'" />');
        break;

      }
      $compile(el)(scope);
      element.append(el);


    }
  };
});	



ModuleConfigQuestions.controller('ctrlListQuestionnaires',function ($location,$scope,$http,$rootScope,$cookies){
    
    $scope.formdata = {};
    
    $scope.questions = 
    [
        {q_id:1,q_title:'First',q_type:'bool',answers:{13:'Yes',14:'No'} },
        {q_id:2,q_title:'Second',q_type:'bool',answers:{15:'Yes',16:'No'} }
    ]
    
    
    
    $scope.updateConfigData = function(){
        console.log( $scope.formdata );
    }

}); 
<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@1.4.1" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-route.min.js"></script>
    <script src="http://dev.simplifi.org/patients/js/ui-bootstrap-tpls-0.13.0.min.js"></script>
    <script src="http://dev.simplifi.org/patients/js/angular-cookies.min.js"></script>
    <script src="http://dev.simplifi.org/patients/js/angular-sanitize.min.js"></script>

    <script src="script.js"></script>
  </head>

  <body>
    
    <form ng-app="ModuleConfigQuestions" ng-controller="ctrlListQuestionnaires" ng-submit="updateConfigData()" novalidate class="form-horizontal" name="questionnaires">
    <accordion close-others="true">

                    <!--Show segment questions-->
                    <accordion-group ng-repeat="(key, question) in questions" id="q_{{question.q_id}}"> 
                        <accordion-heading>{{question.q_title}}</accordion-heading>
                        <div class="panel-body">
                            <custom-question qdata="question"></custom-question>
                        </div>
                    </accordion-group>

                </accordion>
                <br>
                <br>
                
                <input type="submit" vakue="Submit" />
</form>
    
    
  </body>

</html>

在这种情况下,您需要使用$parent来访问控制器的范围。从指令访问Controller的范围有各种其他方法,但在这种情况下$parent是最简单的解决方案。