-->

Angular controlling a list of objects visibility o

2019-08-25 02:12发布

问题:

In AngularJs if you had 2 lists and the second list depended on the values of the first list, it would automatically update. This could be done simply like this:

function toDoCtrl($scope) {  
  $scope.questions = [
    {
      active: true,
      text: "Question 1",
      answers: [
        {
          text: "Answer 1"
        },
        {
          text: "Answer 1"
        },
        {
          text: "Answer 3"
        }
      ]
    },
    {
      active: true,
      text: "Question 2",
      answers: [
        {
          text: "Answer 4"
        },
        {
          text: "Answer 5"
        },
        {
          text: "Answer 6"
        }
      ]
    }
  ];
  $scope.setActive = function(question) {
    question.active = !question.active;
  };
}

Here it is on codepen:

https://codepen.io/r3plica/pen/dQzbvX?editors=1010#0

Now, I want to do the same thing using Angular 6, but it doesn't seem to work....

Here is the same thing using Angular:

https://stackblitz.com/edit/angular-qkxuly

Can someone help me make it work? Or give me some direction?


I have tried to do this myself using this link:

https://blog.thoughtram.io/angular/2016/10/13/two-way-data-binding-in-angular-2.html

But when I updated my stackblitz, it didn't work :(

https://stackblitz.com/edit/angular-jya414

I am going to try something else, because this didn't work. I am surprised no one has posted any possible solutions....I thought this would be a common thing

回答1:

The filter pipe is gone in Angular. From https://angular.io/guide/pipes:

Angular doesn't provide pipes for filtering or sorting lists. Developers familiar with AngularJS know these as filter and orderBy. There are no equivalents in Angular.

They recommend filtering list items in the component logic:

The Angular team and many experienced Angular developers strongly recommend moving filtering and sorting logic into the component itself. The component can expose a filteredHeroes or sortedHeroes property and take control over when and how often to execute the supporting logic. Any capabilities that you would have put in a pipe and shared across the app can be written in a filtering/sorting service and injected into the component.

So for your example, you could do something like this:

questions: Question[] = [
  {
    active: true,
    text: "Question 1",
    answers: [
      {
        text: "Answer 1"
      },
      {
        text: "Answer 1"
      },
      {
        text: "Answer 3"
      }
    ]
  },
  {
    active: true,
    text: "Question 2",
    answers: [
      {
        text: "Answer 4"
      },
      {
        text: "Answer 5"
      },
      {
        text: "Answer 6"
      }
    ]
  }
]
activeQuestions = this.questions.filter(q => q.active);

setActive(question: Question): void {
  question.active = !question.active;
  this.activeQuestions = this.questions.filter(q => q.active);
}

And in the template:

<div *ngFor="let question of activeQuestions">


回答2:

try this

<ng-container *ngFor="let question of questions">
  <div *ngIf="question.active">
    <ul>
      <li *ngFor="let answer of question.answers">{{ answer.text }}</li>
    </ul>
  </div>
</ng-container>

when we add ngFor to iterate on array then we restrict the output using ngIf if true continue and iterate on question.answers ... here's your stackblitz after edit.

there's more than one way to do that by array filter or in dom using ngIf and ngFor choose what suit your needs.