Angular - 如何在不丢失用户输入的情况下在表达式之间切换

时间:2014-07-15 02:19:21

标签: angularjs

我是Angular的新手,所以请尽可能ELI5:)

我有一个多项选择问卷,每个问题的设置如下:

问题

  • 选择A
  • 选择B
  • 选择C

我的控制器看起来像这样:

scope.questionnaire = [
  {
     questionEN: "Thing?",
     choice1EN: "Yes",
     choice2EN: "No",
     choice3EN: "Maybe",
     questionPR: "Treasure?",
     choice1PR: "Yarrr",
     choice2PR: "Arrrrr",
     choice3PR: "Parrrrley"
  }
]

我目前的调查问卷如下:

    <div ng-bind="questionnaire.questionEN"></div>
    <input type="radio" name="{{questionnaire.questionEN}}" ng-model="questionnaire.choice" ng-value="questionnaire.choice1EN">{{questionnaire.choice1EN}}</input> <br />
    <input type="radio" name="{{questionnaire.questionEN}}" ng-model="questionnaire.choice" ng-value="questionnaire.choice2EN">{{questionnaire.choice2EN}}</input> <br />
    <input type="radio" name="{{questionnaire.questionEN}}" ng-model="questionnaire.choice" ng-value="questionnaire.choice3EN">{{questionnaire.choice3EN}}</input>

我想要做的是,在调查问卷开始时,有两个按钮可供用户在语言之间进行选择。

[English] [Pirate]

所以我有两个问题,实际上:

  1. 如何在不丢失用户输入的情况下进行语言交换(例如:他们在[English]中回答了问题1-5,在阅读#6时,向上滚动并按下按钮交换到[Pirate]。他们为1-5选择的答案应该保留,但所有问题+选择都已“翻译”了。

  2. 有没有更好的方法来安排我的控制器?

2 个答案:

答案 0 :(得分:1)

您可以使用ng-click添加功能,然后将$ scope设置为新的调查问卷。

所以你会有这样的事情:

   var english = {
     question: "Thing?",
     answers: {
       choice1: {text: "Yes", val: 1},
       choice2: {text: "No", val: 2},
       choice3: {text: "Maybe", val: 3}
     }
    }

   var pirate= {
     question: "Treasure?",
     answers: {
       choice1: {text: "Yarrr", val: 1},
       choice2: {text: "Arrrrr", val: 2},
       choice3: {text: "Parrrrley", val: 3}
     }
    }
   // default
   $scope.questionnaire = english;
   $scope.choice;
   // change language
    $scope.changeLanguage = function (lang) {
      switch (lang) {
        case 0: 
         $scope.questionnaire = english;
         break;
       case 1: 
         $scope.questionnaire = pirate;
         break;
     }
   }

然后是你的按钮

<button ng-click="changeLanguage(0)">English</button>
<button ng-click="changeLanguage(1)">Pirate</button>

最后,我建议在问卷中使用ng-repeat

<div ng-bind="questionnaire.question"></div>
<label ng-repeat="answer in questionnaire.answers" ><input type="radio" name="{{questionnaire.question}}" ng-model="choice" ng-value="answer.val" />{{answer.text}} <br /></label>

答案 1 :(得分:1)

对此的答案确实因您的特定需求而异。首先开发您要解决的问题的逻辑模型。

要问自己的事情:

  1. 问题是动态的(从数据库加载)还是静态的?
  2. 我如何存储答案?我可以存储选择ID,密钥等,还是必须使用人类可读的值?
  3. 捕获答案的模型是否必须与提出问题的模型不同?
  4. 您是否需要存储他们选择的语言以及答案?
  5. 随着您的思考,其他问题将随之而来。

    无论如何,给你一些接近答案的建议是一个建议。如果问题是动态的,那么您将要创建一个更好的结构来定义问题以及与它们相关的选择。我还给他们一个密钥或ID,以便将它们称为具体概念。这不仅有助于将模型与数据库条目联系起来,使存储和检索变得简单,还可以使您更轻松地处理语言问题。

    Here's an example of such a design.如果您的设计需要,您可能希望单独跟踪答案,在我的情况下,我只是保持简单并将问题和答案保存在一个模型中。

    问题模型是一个对象数组,如下所示:

      {
        key: 'q1', // unique key for question
        text: { // a dictionary of language codes and the text of the question in that language
          'en': 'What is the answer the question 1?',
          'pr': 'Ahoy 1?'
        },
        choices: [{
          key: 'q1a1', // a unique key for the choice
          text: { // a dictionary of language codes and the text of the choice in that language
            'en': 'Answer 1', 
            'pr': 'Arr 1'
          }
        }, {
          key: 'q1a2',
          text: {
            'en': 'Answer 2',
            'pr': 'Arr 2'
          }
        }],
        value: null // the field that stores the user's selected choice
      }
    

    有一个辅助函数可以获取所选选项的语言特定文本:

      $scope.getAnswer = function(question) {
          var answer = $filter('filter')(question.choices, {key: question.value});
    
          if (answer.length == 1) return answer[0].text[$scope.selectedLanguage];
    
          return '(no answer)';
      };
    

    显示问题的HTML模板的内容如下所示:

    <div ng-repeat="question in model">
      <label>{{question.text[selectedLanguage]}}</label>
      <div>
        <label ng-repeat="choice in question.choices">
          <input type="radio" name="{{question.key}}" ng-value="choice.key" ng-model="question.value" />{{choice.text[selectedLanguage]}}
        </label>
      </div>
    
    </div>
    

    替代

    对于它,here's yet another example如何做到这一点。如果您没有动态问题/选择数据,此方法很有用,但仍可以使用一些工作来动态数据。它涉及将本地化的UI字符串保存在单独的表中,分配问题和选择唯一键,然后使用翻译服务来检索正确的字符串。在此示例中,我使用angular-translate模块。我在模块的.config期间加载了本地化字符串表,指定了默认语言,并在显示问题和选择时使用translate过滤器。这让我大大简化了我的问题模型,并在视图和控制器中省去了一些额外的工作。

    我的问题变成了:

    {
      key: 'q1',
      choices: [
        'q1a1',
        'q1a2'
      ],
      value: null
    }
    

    我在语言下拉列表中添加了一个监视来更改当前语言:

      $scope.$watch('selectedLanguage', function(value) {
          if (value === null) return;
          $translate.use(value);
      });
    

    清理模板:

      <label>{{question.key | translate }}</label>
      <div>
        <label ng-repeat="choice in question.choices">
          <input type="radio" name="{{question.key}}" ng-value="choice" ng-model="question.value" />{{ choice | translate }}
        </label>
      </div>