1

On my page I have a dynamic list of musicians (players) whereas a player can be removed and added to the list. Each player shall have multiple instruments which is also a dynamic list, whereas an instrument can be added or removed from a player's instrument list. So we are talking about two nested dynamic lists.

Here is the code and the problem description under it.

jamorg.html:

<!DOCTYPE html>
<html ng-app='jamorgApp'>
<head>
    <link rel="stylesheet" type="text/css" href="C:\Users\jazzblue\Documents\Bootstrap\bootstrap-3.3.2-dist\css\bootstrap.min.css" />
    <title>Jam Organizer</title>
</head>

<body>
<div ng-controller='JamOrgController as jamOrg'>
<h1>Jam</h1>
<div ng-repeat='player in players'>

    <div>
        <h3 style="display: inline-block;">player {{$index}}</h3>
        <button ng-click="removePlayer($index)">Remove</button>
    </div>

    <br/>


    <div ng-controller='JamOrgPlayerController as jamOrgPlayer'>
        <div ng-repeat='instrument in player'>
            <span>Instrument: {{instrument.instrument}},</span>
            <span>Level: {{instrument.level}}</span>
            <button ng-click="remove($index)">Remove</button>
        </div>

        <button ng-click="addInstrument()">Add Instrument</button>
        Instrument: <input ng-model='newInstrument.instrument'>
        Level: <input ng-model='newPlayer.level'>
    </div>

</div>
</div>
    <script type="text/javascript" src="C:\Users\jazzblue\Documents\AngularJS\angular.min.js"></script>
    <script type="text/javascript" src="jamorgApp.js"></script>
</body>
</html>

jamorgApp.js

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

app.controller('JamOrgController', ['$scope', function($scope){
    $scope.players = players;

    $scope.removePlayer = function(index) {
        $scope.players.splice(index, 1);
    } 

    }]);

app.controller('JamOrgPlayerController', ['$scope', function($scope){

    $scope.newInstrument = newInstrument;

    $scope.remove = function(index) {
        $scope.player.splice(index, 1);
    } 

    $scope.addInstrument = function() {
        $scope.player.push(newInstrument);
    } 

}]);

var players = [
    [{instrument: 'Guitar', level: 3}, {instrument: 'Keyboard', level: 3}],
    [{instrument: 'Bass', level: 4}],
    [{instrument: 'Drums', level: 3}]
];

var newInstrument = [
    {instrument: 'x', level: 'y'}
]

Here is my problem: the same newInstrument is being added to all the different players lists which is wrong: each player's instrument list should have its own newInstrument.

How should I change it to get the right design? Thanks!

2 Answers 2

2

Where you do:

$scope.addInstrument = function() {
        $scope.player.push(newInstrument);
    } 

Try doing:

$scope.addInstrument = function() {
        $scope.player.push(angular.copy(newInstrument));
    } 

Update:

In your HTML:

<button ng-click="addInstrument(player)">Add Instrument</button>

In your JS:

$scope.addInstrument = function(player) {
            player.push(angular.copy(newInstrument));
        }

UPDATE

I created a fiddle where you can check some possible modifications to your code. It uses just one controller and fixes the duplicated object issues.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks, but it does not appear to work. As with the original code, anything that is entered (in the browser) as new instrument for player 1 is automatically replicated to all other players, meaning that I did copy the object but that one copy went to all the players.
Hmmm now i am seeing your code again. What is $scope.player? Because i see $scope.players but not $scope.player. Check my updated answer to see if it works.
I think you did find a bug with $scope.player, I give you a point for your comment, however, the solution you suggest still does not work for me. I think, the problem is that the same copy of newInstrument is pushed to different players. I need, however, a separate copy for each player or something like that. Have you tried your suggestion? Thanks.
@jazzblue can you create a fiddle with your code and share? It might help us understanding it and helping you.
I cannot run that fiddle. It throws an error. Anyway, i tried it on my computer and it works but once you add a new instrument and then continue typing in the input, the just added instrument is modified too. I worked on some code that removes all your controllers (i think it is unnecessary to have so many controllers for your little piece of code) and works OK to. Check this fiddle: jsfiddle.net/6Lxw70cy/1 .
|
1
<button ng-click="addInstrument($index)">Add Instrument</button>
    Instrument: <input ng-model='newInstrument.instrument'>
    Level: <input ng-model='newPlayer.level'>

and your addInstrument function should be like this

$scope.addInstrument = function(index) {
    $scope.players[index].push($scope.newInstrument);
}

4 Comments

Thanks, but this still does not work properly: on the page when you type value of "new instrument" in the text box for Player 1 it is automatically replicated to "new instrument" of all other players while you are typing. I need different instances of that model for different players. Is there any way to achieve it? Thanks.
you need just something like in this in your ng-model newInstrument[$index].instrument and newPlayer[$index].level. it will creat separate model for each player.
Actually I found a way: I need a separate controller for NewInstrument, then it will create "separate instances". Your suggestion to use ng-model was very valuable. Thanks.
i am glad that you sort it out.Happy to Help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.