2

I have a collection of rooms in my $scope, with the structure:

$scope.model.rooms = [
    { RoomNumber: 1, Type: 'Single'}, 
    { RoomNumber: 3, Type: 'Single'}, 
    { RoomNumber: 5, Type: 'Double'}, 
    { RoomNumber: 6, Type: 'Single'}, 
    { RoomNumber: 12, Type: 'Double'}
];

I then create a 5x5 grid on my view as follows, and want to have the correct room type selected on the drop down, but I don't know how to do this binding properly.

<div data-ng-repeat="y in [1, 2, 3, 4, 5]" class="hotelRooms">
    <div data-ng-repeat="x in [1, 2, 3, 4, 5]">
        <h6>
            Room #{{(y-1)*5+x}}
            <select id="binType{{(y-1)*5+x}}" data-ng-model="model.rooms[/*WHAT DO I PUT HERE?*/].Type" data-ng-change="setRoomType((y-1)*5+x)">
                <option value="Single">Single</option>
                <option value="Double">Double</option>
            </select>
        </h6> 
        <div id="bin{{(y-1)*5+x}}" data-droppable="{{(y-1)*5+x}}" data-drop="addToRoom">
            <div id="{{p.Id}}" data-draggable="" data-ng-repeat="p in model.participants | filter:{RoomNumber:(y-1)*5+x}">{{p.Name}}</div>
        </div>
    </div>
</div>

The array index isn't the same as the RoomNumber property.

2
  • 2
    Are you trying to fill the select with the model? The model of a select is going to be whatever the selected object is. Commented Apr 22, 2014 at 2:38
  • @J.Wells, The select already has the options Single and Double, the model has an array of rooms. When I draw Room #1, I want to set the drop down to the Type value in the rooms array, where RoomNumber equals 1 Commented Apr 22, 2014 at 17:52

1 Answer 1

1

I find it much more intuitive if you put all of your behavior into your controller. Your view just binds to those behaviors (a la MVVM). You get more control over your code this way and aren't at the mercy of {{binding syntax}} and its limitations.

I removed the drag and drop stuff, but here's how I got it to work. Notice you don't need the ngChange directive in the select because this way it's bound right to the room model Type property. So they stay in sync when you change it.

Here's a fiddle with the working code, or just see below: http://jsfiddle.net/854wk/7/

Controller:

function MyController($scope) {
    $scope.calcBin = calcBin;
    $scope.getRoomByBin = getRoomByBin;

    function calcBin(row, col) { 
        return ((row - 1) * 5) + col;
    };

    function getRoomByBin(row, col) {
        var bin = calcBin(row, col);
        var foundRoom;
        $scope.model.rooms.some(function(room) {
            if (room.RoomNumber === bin)
            {
                foundRoom = room;
                return true; // break
            }
        });
        return foundRoom;
    }
}

View:

<div ng-app>
    <div ng-controller="MyController">
        <div data-ng-repeat="y in [1, 2, 3, 4, 5]" 
             class="hotelRooms">
            <div data-ng-repeat="x in [1, 2, 3, 4, 5]">
                 <h6>
            Room #{{calcBin(y,x)}}
            <select id="binType{{calcBin(y,x)}}" 
                     data-ng-model="getRoomByBin(y,x).Type" >
                <option value="Single">Single</option>
                <option value="Double">Double</option>
            </select>
            Room Type is: {{getRoomByBin(y,x).Type}}
        </h6> 
        </div>
    </div>
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

I'm not using ngChange to bind, but to trigger a save on the server, I probably should change it to a $watch though; so that decision is in the controller not the view. I like the calcBin and getRoomByBin approach better than the solution I came up with, which was changing to a sparsed array with the rooms at the corresponding index.
That makes sense. Using ngChange to persist the change to the server. A bit chatty, but then who likes "Save" buttons nowadays anyway? Note: I changed my solution a tiny bit by removing that findRoom() method. It was stupid.

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.