在AngularJs中动态显示/隐藏元素

4
我目前正在尝试使用Angular,但我遇到了一个问题。我从API获取了一组问题,其中一些问题依赖于其他问题是否被选中为“是”,对于单选按钮问题,此属性的值将在ReliesOnID中。如果我选中“是”,那么依赖于当前选择的问题的问题需要显示出来。
由于我之前使用jQuery,所以我想用一个函数传递reliesonid作为问题编号,并执行类似于$('#question' + reliesonid').show()的操作。
在重复区域内,如何使单选按钮在我点击“是”时显示其他问题?我陷入了困境已经很长时间了,非常感谢您的帮助。以下是我的代码:
<div id="question{{question.Number}}" ng-repeat="question in questions" ng-class="question.ReliesOnID == null ? 'here' : 'hidden'">
    <div ng-if="question.QuestionTypeID == 3" >
        <div class="row">
            <div class="col-xs-12">
                <h5>{{question.Question}}</h5>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-2">
                <div class="col-xs-4"></div>
                <div class="col-xs-8">
                    <input type="radio" value="yes" name="{{question.Number}}"  /><label>Yes</label>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-2">
                <div class="col-xs-4"></div>
                <div class="col-xs-8">
                    <input type="radio" value="no" name="{{question.Number}}" /><label>No</label>
                </div>
            </div>
        </div>
    </div>
    <div ng-if="question.QuestionTypeID == 1">
        <div class="row">
            <div class="col-xs-12">
                <h5>{{question.Question}}</h5>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-4">
                <input type="text" class="form-control" />
            </div>
        </div>
    </div>
</div>


编辑:数据结构为:

{
    "Active": true,
    "Comments": false,
    "DecimalPlaces": 0,
    "F": false,
    "FP": false,
    "Grouped": null,
    "ID": 20500,
    "Length": false,
    "MP": true,
    "Multiline": false,
    "Number": 45,
    "NumericOnly": false,
    "Optional": false,
    "Question": "How long ago was the treatment?",
    "QuestionID": 45,
    "QuestionSectionID": 2,
    "QuestionTypeID": 2,
    "QuestionnaireID": 298,
    "ReliesOnAnswer": true,
    "ReliesOnID": 44,
    "Weight": false
}

问题是当我点击“是”单选按钮时,无法显示一个问题。所以这个问题将会有一个ID为question42,所以我需要找到这个元素并在单选按钮点击时显示它。在jQuery中,我会做一些类似于下面的操作:function test(reliesonid) { $('#question' + reliesonid).show();} - Will2070
@Will2070,你能否展示一下你的jsfiddle,以便我们了解你问题的依赖关系?如果可能的话,请展示一下你的JSON对象。 - Mohit Tanwani
@加载中..我已经在上面添加了一个问题的JSON对象。它依赖于questionid,这是它依赖的问题的编号,即Number属性。 - Will2070
@Will2070 我认为这个 JSON 数据将在 ng-repeat 中作为问题,每个问题都会有一个单选按钮,一旦我选择“是”,它就会显示带有 44 的问题,对吗? - Mohit Tanwani
@加载中.. 这正是我想要发生的,只是我不知道如何做。 - Will2070
显示剩余2条评论
4个回答

1

你需要使用 ng-model 来处理答案,例如:
<input type="radio" value="yes" ng-model="question.Answer" name="{{question.Number}}"/><label>Yes</label>

然后在该问题中,你可以有子问题并使用 ng-repeat

ng-if="question.subQuestions && question.Answer !== undefined" ng-repeat="subquestion in question.subQuestions"

这当然取决于你的问题结构

编辑
基于你的结构,我会说你需要在 ng-repeat 中加入一个类似下面的 ng-if:
ng-if="!question.ReliesOnID || wasAnswered(question.ReliesOnID)"

wasAnswered 函数中,你需要访问 questions 数组,并过滤该 ID 并检查是否已回答并返回 truefalse


1

尝试这个代码片段。

这是你正在寻找的东西吗?

我试图理解你的问题,并根据你的JSON数据结构创建了一个示例。

根据特定问题的选择,它将仅显示其答案。

编辑-1:应用Angular Element

如果已经安装jQuery,则angular.element是jQuery函数的别名。如果没有安装jQuery,则angular.element委托给Angular内置的jQuery子集,称为“jQuery lite”或jqLite。

更多信息angular.element

如果需要,您可以从代码中消除jQuery。

您可以使用angular.element来进行设置/获取类,如此处所示over here

var myApp = angular.module('myApp',[]);

myApp.controller('GreetingController', ['$scope', function($scope) {
  $scope.questions = [
    {
    "Active": true,
    "Comments": false,
    "DecimalPlaces": 0,
    "F": false,
    "FP": false,
    "Grouped": null,
    "ID": 20500,
    "Length": false,
    "MP": true,
    "Multiline": false,
    "Number": 45,
    "NumericOnly": false,
    "Optional": false,
    "Question": "How long ago was the treatment?",
    "QuestionID": 45,
    "QuestionSectionID": 2,
    "QuestionTypeID": 2,
    "QuestionnaireID": 298,
    "ReliesOnAnswer": true,
    "ReliesOnID": 10,
    "Weight": false,
    "Answer": '2 years ago'
    },
    {
    "Active": true,
    "Comments": false,
    "DecimalPlaces": 0,
    "F": false,
    "FP": false,
    "Grouped": null,
    "ID": 20500,
    "Length": false,
    "MP": true,
    "Multiline": false,
    "Number": 45,
    "NumericOnly": false,
    "Optional": false,
    "Question": "Who is God of cricket?",
    "QuestionID": 45,
    "QuestionSectionID": 2,
    "QuestionTypeID": 2,
    "QuestionnaireID": 298,
    "ReliesOnAnswer": true,
    "ReliesOnID": 20,
    "Weight": false,
    "Answer": 'Sachin Tendulkar'
    }
  ]
  
  //Function when radio button clicked
  $scope.flagChange = function(){
    var reliesId = angular.element(event.target).attr('data-reli-id');
    var value = angular.element(event.target).attr('data-value');
    //Based on the condition it will show / hide the respective element
    if(value == "yes")
    {
      $('#'+reliesId).removeClass('hide').addClass('show');
    }
    else
    {
      $('#'+reliesId).removeClass('show').addClass('hide');
    }
  }
}]);
.show
{
  display: block; 
}
.hide
{
  display: none; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="GreetingController">
  <div ng-repeat="question in questions track by $index">
        {{question.Question}}
        <input type="radio" name="Flag_{{$index}}" ng-click="flagChange($event)" data-value="yes" data-reli-id='{{question.ReliesOnID}}' />Yes
        <input type="radio" name="Flag_{{$index}}" ng-click="flagChange($event)" data-value="no" data-reli-id='{{question.ReliesOnID}}' />No
        <span ng-show="custom_$index">{{question.Answer}}</span>
    <br/>
        <div id="{{question.ReliesOnID}}" class="hide">
            Question based on ReliesOnID : {{question.ReliesOnID}}
        </div>
    <br/>
  </div> 
</div>


这是不错的方向,但不是我正在寻找的。例如,您有两个单选按钮。一个是“是”,另一个是“否”。如果选中“是”,它需要检查当前问题是否具有relysonid,并且如果是,则需要找到该问题并显示它。例如,在jQuery中,我将执行函数toggleQuestion(relysonid){ $('#question' + reliesonid').show();} 它们还需要是单选按钮而不是复选框。 - Will2070
@Will2070 我已经编辑了我的答案,请现在查看。根据单选按钮的选择,它将显示replies id的div。这只是一个示例,您可以根据需要进行更改。 - Mohit Tanwani
@Andurit:感谢您的点赞,angular.element在您需要具有复杂HTML结构的更动态元素时非常有用,另一个选项是您可以应用多个动态ng-model。 - Mohit Tanwani
@加载中.. 感谢您的回复,但还不太完整。当您点击“是”时,它需要显示实际的问题元素,因此具有reliedonid的问题在加载时被隐藏,然后当我点击“是”时,它需要显示该问题下面的内容,这可能是另一个带有“是”或“否”的单选按钮问题。 - Will2070
感谢您的留言@Will2070,请尝试理解我们试图让您理解的概念。不要去等待您正在寻找的确切答案。我尝试向您解释了每个场景以实现这一点。因此,现在请根据我为您提供的答案和理解自行尝试 :) - Mohit Tanwani
显示剩余2条评论

0

编辑:根据下面的评论和提供的数据结构:

如果假设您只想迭代那些在开始时是父级且与任何内容无关的问题。当比率设置为true时,相关内容应该仅显示:

因此,请使用ng-repeat-start替换您的ng-repeat,这将使您能够迭代多个div,而不仅仅是其中一个。

在您的<div>元素中添加:

 <input type="radio" ng-model="question.subQuestion" value="true"> <br/>
 <input type="radio" ng-model="question.subQuestion" value="false"> <br/>

接下来再创建一个 <div>,用于显示相关问题。它可以长这样:

// ng-if here to display only when radio was set to true
<div class="relatedQuestion" ng-repeat-end ng-if="question.subQuestion">
  <div ng-repeat="relatedQ in getRelatedQuestion(question.Number)">
    // Here you display your related questions
  </div>
</div>

所以在你的控制器中,你需要添加一个函数:

function getRelatedQuestion(number) {
  // logic comes here which filter question
  // which have property relatedOnId === number;
  // it should be an array of objects to iteratee over it.
}


JQUERY 提供的选项在 Angular 中也是可行的。 不过可能有更简单的解决方案。

在您的 ng-repeat 解决方案中,您可以将单选输入替换为以下内容:

 <input type="radio" ng-model="question.subQuestion" value="true"> <br/>
 <input type="radio" ng-model="question.subQuestion" value="false"> <br/>

然后在下面添加这个:

 <div ng-if="question.subQuestion">
     // Your subQuestion code comes here
 </div>

所有内容都将在您的ng-repeat中,并且应该在控制器中没有额外逻辑的情况下正常工作。


这是否意味着我需要将一个名为subquestion的属性附加到问题作用域? - Will2070
该问题具有一个名为reliesonid的属性,如果它不等于null,则依赖于另一个。 - Will2070
一个问题包括以下内容:Active : true Comments : false DecimalPlaces : 0 F : false FP : false Grouped : null ID : 20500 Length : false MP : true Multiline : false Number : 45 NumericOnly : false Optional : false Question : "治疗是多久以前进行的?" QuestionID : 45 QuestionSectionID : 2 QuestionTypeID : 2 QuestionnaireID : 298 ReliesOnAnswer : true ReliesOnID : 44 Weight : false - Will2070
很酷,谢谢。我已经编辑了你的问题,并在其中添加了JSON数据结构。我的最后一个问题是:ReliesOnID是它所依赖的唯一问题ID吗? - Andurit
ReliesOnID是问题依赖的问题编号,而不是它所依赖的问题ID :) - Will2070
显示剩余3条评论

0

我不喜欢使用ng-if,因为它会向DOM添加和删除元素。以下是关于ng-show/hide的链接以及在scotch.io上如何使用它的教程。

https://docs.angularjs.org/api/ng/directive/ngShow

https://scotch.io/tutorials/how-to-use-ngshow-and-nghide

一个快速的例子如下,当变量is_active为真时(div元素将只显示这个条件),这个检查可以使用布尔值或文本检查。这个变量可以在控制器或视图中设置,你不需要切换它。当评估结果不为真时,div将自动隐藏;因此,除非你正在针对多个条件进行检查,否则不需要在同一元素上使用ng-hide和ng-show。
<input type="radio" ng-model="question.subQuestion" value="true"> <br/>
 <input type="radio" ng-model="question.subQuestion" value="false"> <br/>

 <div ng-show="question.subQuestion">
     // Your subQuestion code comes here
 </div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接