0

I'm using this plugin called Dragula which needs an ObservableArray as a source for the data..

HTML/Knockout-bindings

<div class="widget-container">
                <div class="widget-content visible" id="team-setup">
                    <div class="header">
                        <p>Lagoppsett</p>
                        <p></p>
                    </div>

                    <div class="col-sm-12">
                        <div class="row">
                            <div class="widget-container">
                                <div class="col-xs-6 widget-content visible">
                                    <div class="header">
                                        <p>Tilgjengelige spillere</p>
                                        <p></p>
                                    </div>
                                    <div class="player-card-container-mini" data-bind="dragula: { data: availablePlayers, group: 'playerz' } ">

                                        <div class="player-card-mini">
                                            <div class="player-card-left">
                                                <div class="player-avatar" style="margin-left: 85%;">
                                                    <img src="Content/Images/player-female.png" id="imgAvatar" runat="server" />
                                                    <div class="player-shirt-no" data-bind="text: ShirtNo"></div>
                                                </div>
                                            </div>
                                            <div class="player-card-subtext">
                                                <div class="player-text">
                                                    <div class="player-card-header-small" data-bind="text: PlayerName"></div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                                <div class="col-xs-6 widget-content visible">
                                    <div class="header">
                                        <p>Lag</p>
                                        <p></p>
                                    </div>
                                    <div data-bind="foreach: teamsetup">
                                    <div data-bind="foreach: SubTeams">
                                        <h1 data-bind="text: TeamSubName"></h1>
                                        <div class="player-card-container-mini" data-bind="dragula: { data: Players, group: 'playerz' } " style="border: 1px solid red; min-height:200px">

                                            <div class="player-card-mini">
                                                <div class="player-card-left">
                                                    <div class="player-avatar" style="margin-left: 85%;">
                                                        <img src="Content/Images/player-female.png" id="img1" runat="server" />
                                                        <div class="player-shirt-no" data-bind="text: ShirtNo"></div>
                                                    </div>
                                                </div>
                                                <div class="player-card-subtext">
                                                    <div class="player-text">
                                                        <div class="player-card-header-small" data-bind="text: PlayerName"></div>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    </div>
                                </div>
                        </div>
                    </div>
                    <div style="clear:both">&nbsp;</div>
                </div>
            </div>

Knockout code :

var TeamSetupViewModel = function () {
    var self = this;
    self.teamsetup = ko.observableArray();
    self.availablePlayers = ko.observableArray();
    self.testPlayers = ko.observableArray();
}
var model = new TeamSetupViewModel();

ko.applyBindings(model, document.getElementById("team-setup"));

var uri = 'api/MainPage/GetTeamSetup/' + getQueryVariable("teamId");

$.get(uri,
    function (data) {
        model.teamsetup(data);
        model.availablePlayers(data.AvailablePlayers);
        model.testPlayers(data.AvailablePlayers);
        console.log(data);
    }, 'json');

});

The problem is... that i'm having a ObservableArray at the top node, and i do need ObservableArrays further down in the hierarchy.

model.availablePlayers works fine, but when accessing the other players in the html/ko foreach loops through teamsetup -> SubTeams -> Players it doesn't work due to Players isn't an ObservableArray. (There might be everyting from 1 to 7 SubTeams with players).

So how can i make the Players in each SubTeams an ObservableArray ?

See the image for the datastructure :

enter image description here

6
  • Can you show your view where you have all your foreach Commented Mar 30, 2016 at 3:58
  • Have you considered the Knockout mapping plugin? Commented Mar 30, 2016 at 4:00
  • @Matt.k : Question updated with HTML. Commented Mar 30, 2016 at 6:42
  • @Neps : Never used it :) Will that assist with this issue ? Commented Mar 30, 2016 at 6:43
  • It can help you create a view model automatically with observable arrays matching your data model. Note that if just need one-way data-binding, regular arrays will suffice Commented Mar 30, 2016 at 7:10

1 Answer 1

1

You could use Mapping plugin, but if players is the only thing you need, you can do it manually:

Simplify your view model:

var TeamSetupViewModel = function () {
    var self = this;
    self.availablePlayers = ko.observableArray();
    self.subTeams = ko.observableArray();
}

After you get the data from the server, populate the view model converting the array of players on every team to an observable array of players:

$.get(uri,
    function (data) {
        model.availablePlayers(data.AvailablePlayers);
        model.subTeams(data.SubTeams.map(function(t) { t.Players = ko.observableArray(t.Players); return t; }));
    }, 'json');
});

Finally, remove the following line in your template (with its closing tag) - nothing to iterate over anymore:

<div data-bind="foreach: teamsetup">

... and update the name of the property in the next line, so it is camel case like in the VM:

<div data-bind="foreach: subTeams">
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a bunch Maciej !

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.