AngularJS ng-repeat并选择控制更新所有实例

时间:2015-08-13 12:42:07

标签: angularjs

我有这个HTML:

<div class="table-responsive">
    <table class="table">
        <thead>
            <tr>
                <th>Name / Number</th>
                <th>Gender</th>
                <th>Quantity</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="player in item.players">
                <td>{{ player.name }}</td>
                <td>
                    <select class="form-control input-lg" ng-model="player.gender" ng-options="gender.id as gender.title for gender in item.garment.modifiers[0].variants" ng-change="controller.updateCart(item)">
                        <option value="">Please select</option>
                    </select>
                </td>
                <td>
                    <select class="form-control input-lg" ng-model="player.qty" ng-change="controller.updateCart(item)">
                        <option ng-repeat="qty in garmentController.quantities">{{ qty }}</option>
                    </select>
                </td>
                <td>
                    <button class="btn btn-lg btn-danger btn-icon-only btn-icon-only" type="button" ng-click="garmentController.remove(item, player)"><span class="fa fa-close"></span></button>
                </td>
            </tr>
        </tbody>
    </table>
</div>

此表位于另一个ng-repeater中,如下所示:

<div class="panel panel-order" id="{{ item.garment.slug }}" ng-repeat="item in garmentController.order.items">
    <div class="row">
        <div class="col-md-2 text-center">
            <label class="control-label">{{ item.garment.title }}</label>

            <div class="kit-template" garment="item.garment" colours="controller.kit.data.colours" on-complete="garmentController.onLoad(item.garment.slug)" kd-kit-designer></div>

            <p class="lead">{{ item.garment.price.price }}</p>
        </div>

        <div class="col-md-4">

            <div kd-garment-current-configuration="{{ item.garment.slug }}" ng-if="garmentController.hasLoaded(item.garment.slug)">
                hello
            </div>

        </div>

        <div class="col-md-6">

            <div alert type="info" ng-if="!garmentController.fulfilledQuantities(item)">
                Please be aware that we can not accept order quantities less than 10 per item. Adjust your quanities below to fix this issue.
            </div>

            <div class="table-responsive">
                <table class="table">
                    <thead>
                        <tr>
                            <th>Name / Number</th>
                            <th>Gender</th>
                            <th>Quantity</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr ng-repeat="player in item.players">
                            <td>{{ player.name }}</td>
                            <td>
                                <select class="form-control input-lg" ng-model="player.gender" ng-options="gender.id as gender.title for gender in item.garment.modifiers[0].variants" ng-change="controller.updateCart(item)">
                                    <option value="">Please select</option>
                                </select>
                            </td>
                            <td>
                                <select class="form-control input-lg" ng-model="player.qty" ng-change="controller.updateCart(item)">
                                    <option ng-repeat="qty in garmentController.quantities">{{ qty }}</option>
                                </select>
                            </td>
                            <td>
                                <button class="btn btn-lg btn-danger btn-icon-only btn-icon-only" type="button" ng-click="garmentController.remove(item, player)"><span class="fa fa-close"></span></button>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>

        </div>
    </div>
</div>

假设我有3个项目,但每个项目只有1个玩家,当我更改数量下拉列表时,所有项目下拉列表都会更改为该值,我不知道为什么。 有人可以帮我阻止这样做吗?

我创建了一个codepen来突出显示问题,但是codepen实际上做了我想要的。

http://codepen.io/r3plica/pen/vOMeZW?editors=101

我不知道为什么那个工作正常,因为我静态声明的顺序是我的开发机器上测试输出的精确副本。

更多信息

只是为了更容易猜出可能发生的事情,以下是我的做出决定的决议:

// Get the kit we are ordering
kit: ['$stateParams', 'KitService', function ($stateParams, service) {

    // Return our kit
    return service.get($stateParams.kitId);
}],

// Get he team that the kit belongs to
team: ['kit', function (kit) {

    // Return our team
    return kit.data.team;
}],            

// Get the garments assigned to the kit
garments: ['$q', 'Moltin', 'kit', function ($q, moltin, kit) {

    // Get the garments
    var garments = kit.data.garments;

    // Create our deferred promise
    var deferred = $q.defer();

    // Create our array of promises
    var promises = [];

    // Create our array of results
    var results = [];

    // Loop through our garments
    for (var i = 0; i < garments.length; i++) {

        // Get our garment
        var garment = garments[i];

        // Push our promise to our promises array
        promises.push(moltin.products.get(garment.slug).success(function (response) {

            // Combine both models
            var combined = angular.extend(response[0], garment);

            // Push our result into our results array
            results.push(combined);
        }));
    }

    // Resolve all our promises
    $q.all(promises).then(function () {

        // Resolve our results
        deferred.resolve(results);
    });

    // Return our promise
    return deferred.promise;
}],

// Get the players already added to the team
players: ['team', function (team) {

    // Return our players
    return team.players;
}],

// Gets the customer if they have placed an order before, if not it will return the new customer to be created
customer: ['$rootScope', 'Moltin', function ($rootScope, moltin) {

    // Get our user
    var user = $rootScope.user;

    // If we have a customer id
    if (user.customerId) {

        // Get our customer
        return moltin.custsomers.get(user.customerId);
    }

    // If we don't have a customer id return the new customer object
    return {
        first_name: user.firstName,
        last_name: user.lastName,
        email: user.email
    };
}],

// Gets the stored addresses if we have a customer
addresses: ['customer', 'Moltin', function (customer, moltin) {

    // If we have a customer id
    if (customer.id) {

        // Get our addresses
        return moltin.customers.addresses(customer.id);
    }

    // Return nothing fallback
    return null;
}],

// Create our order
order: ['garments', 'players', function (garments, players) {

    // Create our order
    var order = {
        items: []
    };

    // Loop through our garments
    for (var i = 0; i < garments.length; i++) {

        // Get our current garment
        var garment = garments[i];

        // Create our item
        var item = {
            garmentId: garment.id,
            garment: garment,
            players: players
        };

        // Push our items to our array
        order.items.push(item);
    }

    // Return our order
    return order;
}],

1 个答案:

答案 0 :(得分:0)

我怀疑这是因为我将玩家分配给每个订单项目。我实际上正在为玩家阵列分配引用,所以当玩家正在改变时,双向绑定生效并改变了对玩家的所有其他引用。 我解决这个问题的方法是改变订单决心来做到这一点:

// Create our order
order: ['garments', 'players', function (garments, players) {

    // Create our order
    var order = {
        items: []
    };

    // Loop through our garments
    for (var i = 0; i < garments.length; i++) {

        // Get our current garment
        var garment = garments[i];

        var t = [];

        for (var n = 0; n < players.length; n++) {

            var player = players[n];

            t.push({ id: player.id, name: player.name, positionNumber: player.positionNumber, teamId: player.teamId });
        }

        // Create our item
        var item = {
            garmentId: garment.id,
            garment: garment,
            players: t
        };

        // Push our items to our array
        order.items.push(item);
    }

    // Return our order
    return order;
}],

正如你所看到的,我所做的是穿过衣服,然后循环穿过球员。当循环播放器时,我将一个新对象(具有与播放器相同的属性)推送到一个数组,然后我将其分配给项目对象。 这非常难看,但它确实有效。

如果有人有更优雅的解决方案,请告诉我。

原来有一个更好的解决方案

Angular to rescue,你可以简单地使用 angular.copy()来创建对象/数组的副本,如下所示:

// Create our order
order: ['garments', 'players', function (garments, players) {

    // Create our order
    var order = {
        items: []
    };

    // Loop through our garments
    for (var i = 0; i < garments.length; i++) {

        // Get our current garment
        var garment = garments[i];

        // Create our item
        var item = {
            garmentId: garment.id,
            garment: garment,
            players: angular.copy(players)
        };

        // Push our items to our array
        order.items.push(item);
    }

    // Return our order
    return order;
}],