Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

javascript - AngularJS filter based on array of strings?

I'm having a hard time wrapping my head around how to go about doing an Angular filter to solve a problem that I'm running into.

Here's a basic example of my data structure, an array of tasks:

var tasks = [
    { Title: "This is a task title",
      Tags: ["Test","Tag","One","Two","Three"] },
    { Title: "Another test tag title",
      Tags: ["Some", "More", "Tags"] },
    { Title: "One more, why not",
      Tags: ["I","Like","Dirt"] },
    { Title: "Last one!",
      Tags: ["You","Like","Dirt"] }
];

So each object has an array of tags. For the sake of example let's say I am outputting each of those objects as a row in a table.

Once the pages ng-controller is initialized, I'm grabbing all of the tags from all of the tasks (without duplicates) and assembling them into a tags array.

Then, I'm outputting those tags as toggle-able buttons on the page. All the buttons are blue by default, meaning "active" (in other words: show tasks with this tag contained therein). I need to be able to click on one of those buttons to "toggle off" that tag -- which will filter out any tasks rows in the table wherein the task has that tag.

Like so for visual reference -- grey = "hide tasks whose tags contains this tag", blue = "show tasks whose tags contain this tag":

So you'd see a big row of buttons like this.

Clicking on a button turns it grey, filtering out any tasks in the table that have that tag. I can then click the buttons again to toggle that tag back on, re-showing all tasks with that tag.

Am I explaining this clearly enough? It's a confusing system.

Anyway, I've tried the following:

ng-filter="task in filteredWithTags = (tasks | filter: { tags: arrayOfTags }" to no avail.

Someone mind pointing me in the right direction? :)

PS: I had this working earlier this week by calling a filterByTag(tag) function in my controller. This would loop through every task in the array of tasks and if it had the tag that matched, it would hide that task. Similarly re-activating a tag would do the same thing, loop through everyone and work the magic... but I'm told that my method was slow + overkill, because "angular filters can handle all of that for you, and it will be more best-practicy". Hence, why I'm here, trying to figure out how to let Angular do the work for me :)

Any help is appreciated!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could write a custom filter. The filter would be given the list of active tags, tags, and the array of tasks to be filtered, tasks, and would output an array of filtered tags. It will be much the same as what you've already done, but with no extra function on the scope.

angular.module('myApp').filter('selectedTags', function() {
    return function(tasks, tags) {
        return tasks.filter(function(task) {

            for (var i in task.Tags) {
                if (tags.indexOf(task.Tags[i]) != -1) {
                    return true;
                }
            }
            return false;

        });
    };
});

Then you can use it like

<ul>
    <li ng-repeat="task in tasks | selectedTags:tags"></li>
</ul>

Check out this fiddle.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...