简体   繁体   中英

AngularJS nested ng-repeat click & show/hide

I've done a ton of reading and research on this topic the past few days and have found some good answers, but for some of the answers I question performance and necessity.

My question pertains to nested ng-repeat scopes. I'm wondering what the best way to achieve an "add item" scenario for adding an item to the nested foreach.

My Code

My HTML is simply 2 ng-repeat s and my goal is to be able to add an item to the second (nested) ng-repeat

<div ng-app="myApp">
    <div class="nav" ng-controller="FoodsController as vm">
        <div class="level1" ng-repeat="foods in vm.foodGroups">{{foods.Name}}
            <button type="button" ng-click="vm.addNewFood()">add new food</button>
            <div ng-show="vm.newFoodBeingAdded">
                <input type="text">
            </div>
            <div class="level2" ng-repeat="food in foods.FoodsInGroup">{{food.Name}}</div>
        </div>
    </div>
</div>

My Angular controller looks like this:

app.controller('FoodsController', function () {
    var vm = this;
    vm.foodGroups = [{
        "Name": "Grains",
            "FoodsInGroup": [{
            "Name": "Wheat"
        }, {
            "Name": "Oats"
        }]
    }, {
        "Name": "Fruits",
            "FoodsInGroup": [{
            "Name": "Apple"
        }, {
            "Name": "Orange"
        }]
    }];

    vm.newFoodBeingAdded = false;

    vm.addNewFood = function () {
        vm.newFoodBeingAdded = true;
    };
});

What should happen

The general work flow would be a user clicks an Add New button and it shows a text box with a "save" button. The text box & button would be within the parent foreach. Once a user saves the item it would then be added to the nested foreach (that logic isn't shown).

The issue

The issue is that when I click "Add New Food" (which should just show 1 of the text boxes & save buttons), all of the text boxes show. How do I ensure I am "scoping" this correctly and that only the text box/button within that parent are shown?

Possible solution

One answer I found was to create a child controller for each nested item. For example I'd have a FoodGroupsController which would manage all the logic for the nested foreach (because there will be a lot more going on than just adding a new item in a real app, so it could be justified).

jsFiddle

Here's a jsFiddle with the code that currently does not function correctly.

There is the forked Fiddle

I made just few changes. The fact is that you were binding the ng-show with a single var in your controller. It was a show me all or show me nothing possibility. So the fix it, you have to bind this, in your food item, not in the controller himself.

Html :

<button type="button" ng-click="vm.addNewFood(foods)">add new food</button>
    <div ng-show="foods.newFoodBeingAdded" class="add-new-food">
       <input type="text" placeholer="add a new food">
       <button type="button">save new food</button>
</div>

Controller :

vm.addNewFood = function (foods) {
    foods.newFoodBeingAdded = true;
};

With this code, you pass the food in param of your function, so you can change the boolean of your food only. And then, your ng-show is just binding on this boolean.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM