Предварительно проверенное поле ввода не сериализуется

У меня есть простой код, который перечисляет множество цветов и проверяет, были ли некоторые из них выбраны предварительно пользователем (это установлено в коде, но на самом деле оно исходит из базы данных). Когда я отправляю форму, предварительно проверенные входы не отображаются в массиве, и если я сниму отметку с некоторых, они не будут удалены из массива.

const SampleApp = angular.module('SampleApp', [])

SampleApp.controller('sampleAppController', function($scope) {
    $scope.colors = ['red', 'green', 'blue', 'black', 'yellow', 'pink', 'white']
    $scope.preChecked = ['green', 'pink']
    $scope.user = { colors: [] }
    $scope.colorArr = []

    $scope.isUserColor = color => {
         return $scope.preChecked.some(uColor => color === uColor)
    }

    $scope.handleSubmit = () => {
        const filteredColors = $scope.colors.filter((color, index) => {
            return $scope.user.colors.some((uColor, uIndex) => {
                 return index === uIndex
            })
        })
        $scope.colorArr = filteredColors
    }    
})
<html lang="en" ng-app="SampleApp">
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
    </head>
    <div ng-controller="sampleAppController">
        <form ng-submit="handleSubmit()">
            <ul>
                <li ng-repeat="color in colors">
                    <input
                        type="checkbox"
                        name="{{color}}"
                        id="{{color}}"
                        ng-checked="isUserColor(color)"
                        ng-model="user.colors[$index]"
                        value="{{color}}"
                    >
                    <label for="{{color}}">{{color}}</label>
                </li>
            </ul>
            <button>Submit</button>
        </form>
        <div>{{colorArr}}</div>
    </div>
    </body>

</html>


person Jefter Rocha    schedule 23.11.2019    source источник
comment
Не используйте ng-model и ng-checked вместе. Используйте ng-model для двусторонней привязки, ng-checked для односторонней привязки.   -  person georgeawg    schedule 23.11.2019


Ответы (1)


Директивы ng-model и ng-checked не следует использовать вместе1

Из документов:

нгПроверено

Устанавливает проверенный атрибут для элемента, если выражение внутри ngChecked истинно.

Обратите внимание, что эту директиву нельзя использовать вместе с ngModel, так как это может привести к непредвиденному поведению.

Справочник по API директивы AngularJS ng-checked


Не используйте ng-model и ng-checked вместе. Используйте ng-model для двусторонней привязки, ng-checked для односторонней привязки.

<ul>
   <li ng-repeat="color in colors">
        <input
            type="checkbox"
            name="{{color}}"
            id="{{color}}"
            ̶n̶g̶-̶c̶h̶e̶c̶k̶e̶d̶=̶"̶i̶s̶U̶s̶e̶r̶C̶o̶l̶o̶r̶(̶c̶o̶l̶o̶r̶)̶"̶
            ng-model="user.colors[$index]"
            ̶v̶a̶l̶u̶e̶=̶"̶{̶{̶c̶o̶l̶o̶r̶}̶}̶"̶
        >
        <label for="{{color}}">{{color}}</label>
    </li>
</ul>

Вместо этого инициализируйте модели из контроллера:

$scope.user = { colors: [] };
$scope.user.colors = $scope.colors.map(c => $scope.preChecked.some(_ => _ == c));
person georgeawg    schedule 23.11.2019
comment
это решило мою проблему, спасибо! - person Jefter Rocha; 23.11.2019