Я довольно новичок в angularJS. Я пытаюсь создать интерфейс для пользователя, где он сможет выбрать ровно два элемента из двух выпадающих списков. Это на самом деле одинаковые варианты. Когда пользователь выбирает какую-либо опцию из выпадающего списка слева, он не сможет выбрать ту же вещь из выпадающего списка справа и наоборот. У пользователя также будет кнопка для добавления дополнительных параметров. Код работает отлично для всего, но когда пользователь нажимает кнопку, чтобы добавить дополнительные параметры, новые добавленные параметры не работают вообще. Вот мой полный код:

   <html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="MyCtrl">
        <h2>Select one Item from left and one Item from right</h2>
        <select ng-model="leftmodel"
                ng-change="ChangeOptions()"
                ng-options="option as option.value disable
  when option.disabled for option in left">
        </select>

        <select ng-model="rightmodel"
                ng-change="ChangeOptions()"
                ng-options="option as option.value disable when option.disabled for option in right">

        </select>
        <button ng-click="addOptions()">Click Me</button>
    </div>
</div>
<script>
    var module = angular.module("app", []);
    module.controller("MyCtrl",
            function($scope) {
                $scope.left = [{
                    "name": "apple",
                    "value": "Nice Apple",
                    "disabled": false
                }, {
                    "name": "orange",
                    "value": "Yellow Orange",
                    "disabled": true
                }, {
                    "name": "berry",
                    "value": "Blue Berry",
                    "disabled": false
                }];

                $scope.right = [{
                    "name": "apple",
                    "value": "Nice Apple",
                    "disabled": true
                }, {
                    "name": "orange",
                    "value": "Yellow Orange",
                    "disabled": false
                }, {
                    "name": "berry",
                    "value": "Blue Berry",
                    "disabled": false
                }];

                $scope.leftmodel = $scope.left[0];
                $scope.rightmodel = $scope.right[1];
                $scope.addOptions=function()
                {
                    var banana={
                        "name": "banana",
                        "value": "Tasty Banana",
                        "disabled": false
                    };
                    var orange={
                        "name":"orange",
                        "value":"Soour Orange",
                        "disabled":false
                    };
                    $scope.left.push(banana);
                    $scope.left.push(orange);
                    $scope.right.push(banana);
                    $scope.right.push(orange);
                };
                $scope.ChangeOptions = function() {
                    var lsize = $scope.left.length;
                    var rsize = $scope.left.length;
                    for (var i = 0; i < lsize; i++) {

                        console.log($scope.left[i]);
                        if ($scope.left[i].name === $scope.rightmodel.name) {
                            $scope.left[i].disabled = true;
                        } else {
                            $scope.left[i].disabled = false;
                        }
                    }

                    for (var i = 0; i < rsize; i++) {
                        if ($scope.right[i].name === $scope.leftmodel.name) {
                            $scope.right[i].disabled = true;
                        } else {
                            $scope.right[i].disabled = false;
                        }
                    }
                };

            }
    );
</script>
</body>
</html>

У меня также есть Codepen. Ошибки, которые я получаю, нажимая только что созданную опцию при нажатии кнопки:

TypeError: Невозможно прочитать свойство 'name' из null в ChildScope. $ Scope.ChangeOptions (first.html: 89) в fn (eval at compile (angular.js: 15156),: 4: 159) в ChildScope. $ Eval (angular .js: 17972) на angular.js: 25711 на объекте. (angular.js: 28536) в forEach (angular.js: 357) в Object. $$ writeModelToScope (angular.js: 28534) в writeToModelIfNeeded (angular.js: 28527) в angular.js: 28521 в validationDone (angular.js) : 28446 )

Кто-нибудь может мне помочь, как я могу решить эту проблему? Заранее спасибо.

Я заметил еще одну странную вещь. Он может поддерживать имена в строке 88. Но в той же строке произойдет сбой, сказав, что он не может найти name из null в строке 88. Изображение Странная ошибка показывает сценарий.

1
Bigdata Workshop 10 Янв 2017 в 16:08

3 ответа

Лучший ответ

У вас есть два недостатка в вашем коде.

Во-первых, вы помещаете один и тот же объект в массивы left и right в addOptions(). Это означает, что когда вы отключаете объект справа, он автоматически отключается слева (поскольку это один и тот же объект, а не просто два объекта, которые выглядят одинаково). Когда он отключается, то leftmodel больше не является допустимым параметром, поэтому он получает undefined.

Вы можете исправить это, используя angular.copy() для клонирования объекта, создав два отдельных объекта слева и справа.

Вторая проблема заключается в том, что у вас уже есть элемент с именем 'orange' в ваших списках, поэтому, если вы выберете один из них в left, он отключит оба . на right и заставить leftmodel стать undefined (потому что первый 'orange' является параметром по умолчанию для right).

Вот обновленный addOptions():

$scope.addOptions = function() {
  var banana = {
    "name": "banana",
    "value": "Tasty Banana",
    "disabled": false
  };
  var orange = {
    "name": "sorange",
    "value": "Soour Orange",
    "disabled": false
  };
  $scope.left.push(angular.copy(banana));
  $scope.left.push(angular.copy(orange));
  $scope.right.push(angular.copy(banana));
  $scope.right.push(angular.copy(orange));
};

И ответвление вашего кода: https://codepen.io/anon/pen/xgZYmW

1
Claies 11 Янв 2017 в 02:24

У вас есть два for - цикла друг под другом, которые оба используют переменную i в качестве индекса. Javascripts фактически перемещает эти переменные в верхнюю часть области видимости, поэтому интерпретатор создаст что-то вроде этого:

$scope.ChangeOptions = function() {
    var lsize = $scope.left.length;
    var rsize = $scope.left.length;

    var i = 0;
    var i = 0;

    for(i; i < lsize; i++) {
        //
    }

    // After the previous loop, i will be 3
    for(i; i < rsize; i++) {

Это приведет к тому, что второй цикл начнется при i = 3, поэтому он не найдет $scope.right[3].name. Чтобы это исправить, просто измените второй цикл на другую переменную, например j.

0
devqon 10 Янв 2017 в 13:29

Вместо инициализации новых переменных внутри вашего метода addOptions. Возьмите две модели, которые вы уже определили в HTML, и добавьте их в массив с помощью функции:

   $scope.addOptions=function()
            {
                var leftOption = $scope.leftmodel;
                var rightOption = $scope.rightmodel; 

                function newFruit(option){

                    var fruit = {
                    "name": option,
                    "value": "",
                    "disabled": false

                  };

                  return fruit;
                }

                $scope.left.push(newFruit(leftOption));
                $scope.right.push(newFruit(rightOption));
            };
0
23rharris 10 Янв 2017 в 13:52