ng-options не отображает объект ng-model в поле выбора при загрузке (AngularJS)

У меня есть вход для выбора html. Здесь я использую AngularJS:

<select class="form-control" 
    ng-model="t.selected" 
    ng-options="option | matriseValgFilter for option in t.Valgalternativer" 
    ng-change="change(t.selected)">
</select>

Проблема в том, что t.select определен, но не отображается в списке выбора html. Если я что-то выберу, то t.select изменится, и отображаемое значение изменится правильно, я хочу, чтобы он отображал t.select при загрузке.

Это угловой код, сделанный на скрипке для лучшей иллюстрации: /а>

angular.module('app', ['ngAnimate'])

.controller('controller', function($scope) {

  $scope.t = {
    "Tabellnavn": "BE3.2:1",
    "Siffer": "x",
    "Stikkord": "Utvendig kledning:",
    "Tekst": {
      "Format": 0,
      "Content": "{Matrise BE3.2:1}"
    },
    "Merknader": null,
    "Delprodukter": null,
    "Valgalternativer": [{
      "Siffer": "-",
      "Tekst": "{Matrise BE3.2:1}",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }, {
      "Siffer": "00",
      "Tekst": "Valgfri",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }, {
      "Siffer": "11",
      "Tekst": "Murt forblending",
      "Tekst2": null,
      "Kode": "NB2.7---x-",
      "Delalternativer": null
    }, {
      "Siffer": "21",
      "Tekst": "Bordkledning på vegg utvendig – stående bord",
      "Tekst2": null,
      "Kode": "QK2.11xx---",
      "Delalternativer": null
    }, {
      "Siffer": "22",
      "Tekst": "Bordkledning på vegg utvendig – stående ukantede bord",
      "Tekst2": null,
      "Kode": "QK2.12x---",
      "Delalternativer": null
    }, {
      "Siffer": "23",
      "Tekst": "Bordkledning på vegg utvendig – stående spaltekledning",
      "Tekst2": null,
      "Kode": "QK2.15xx---",
      "Delalternativer": null
    }, {
      "Siffer": "24",
      "Tekst": "Bordkledning på vegg utvendig - liggende bord",
      "Tekst2": null,
      "Kode": "QK2.21xx---",
      "Delalternativer": null
    }, {
      "Siffer": "26",
      "Tekst": "Platekledning på vertikal flate utvendig utvendig",
      "Tekst2": null,
      "Kode": "QK5.226--",
      "Delalternativer": null
    }, {
      "Siffer": "31",
      "Tekst": "Kledning med tynnplatekassetter av kopper",
      "Tekst2": null,
      "Kode": "SM4.2--",
      "Delalternativer": null
    }, {
      "Siffer": "32",
      "Tekst": "Kledning med tynnplatekassetter av titansink",
      "Tekst2": null,
      "Kode": "SM4.3--",
      "Delalternativer": null
    }, {
      "Siffer": "33",
      "Tekst": "Kledning med tynnplatekassetter av aluminium",
      "Tekst2": null,
      "Kode": "SM4.4--",
      "Delalternativer": null
    }, {
      "Siffer": "34",
      "Tekst": "Kledning med tynnplatekassetter av varmforsinket stål",
      "Tekst2": null,
      "Kode": "SM4.5--",
      "Delalternativer": null
    }, {
      "Siffer": "35",
      "Tekst": "Kledning med plane metallplater",
      "Tekst2": null,
      "Kode": "SM5.1",
      "Delalternativer": null
    }, {
      "Siffer": "88",
      "Tekst": "Uten utvendig kledning",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }, {
      "Siffer": "99",
      "Tekst": "Annen utvendig kledning – må spesifiseres",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }],
    "selected": {
      "Siffer": "99",
      "Tekst": "Annen utvendig kledning – må spesifiseres",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }
  };

  $scope.change = function(selected) {
    console.log(selected);
  }
})
.filter('matriseValgFilter', function() {

    return function (option) {

        if (!isNaN(option.Siffer) && option.Kode != null){
            return option.Siffer + ' - ' + option.Tekst + ' (' + option.Kode + ')';
        }

        if (!isNaN(option.Siffer)){
            return option.Siffer + ' - ' + option.Tekst;
        }

        return option.Tekst;


    }
});

РЕДАКТИРОВАТЬ: Чтобы уточнить, для t.select установлено значение «99 - Annen utvendig kledning – må spesifiseres», это то, что должно отображаться при загрузке в поле выбора.


person ganjan    schedule 11.02.2016    source источник


Ответы (4)


Объект в t.selected и t.Valgalternativer различается в зависимости от javascript. Потому что их хеш-значения разные. Javascript сравнивает только хеш-значения на равенство. Только мы, программисты, должны учить Javascript, чтобы сравнивать его с полем 'Tekst' вместо '$hash'.
Рабочий JSFiddle - https://jsfiddle.net/Lt0cuwLd/6/

Ниже приведен единственный код, который я добавил. Он просто просматривает каждый элемент в списке и сравнивает его значение «Tekst» со значением «Tekst» t.selected. Если они оба равны, он вернет этот объект, и мы назначим его t.selected. Теперь значение '$hash' t.selected также совпадает, а не только 'Tekst'. В конце концов, компьютер не так умен, как люди :)

$scope.t.selected = $scope.t.Valgalternativer.reduce(function(curr, next){
    if(next.Tekst === $scope.t.selected.Tekst) return next;
    else return curr;
}, {})
person elango.dev    schedule 11.02.2016

Вам нужно инициализировать вашу переменную t.selected вот так $scope.t.selected = $scope.t.Valgalternativer[0];.

Живой пример на jsfiddle.

angular.module('app', ['ngAnimate'])

.controller('controller', function($scope) {
 
  $scope.t = {
    "Tabellnavn": "BE3.2:1",
    "Siffer": "x",
    "Stikkord": "Utvendig kledning:",
    "Tekst": {
      "Format": 0,
      "Content": "{Matrise BE3.2:1}"
    },
    "Merknader": null,
    "Delprodukter": null,
    "Valgalternativer": [{
      "Siffer": "-",
      "Tekst": "{Matrise BE3.2:1}",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }, {
      "Siffer": "00",
      "Tekst": "Valgfri",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }, {
      "Siffer": "11",
      "Tekst": "Murt forblending",
      "Tekst2": null,
      "Kode": "NB2.7---x-",
      "Delalternativer": null
    }, {
      "Siffer": "21",
      "Tekst": "Bordkledning på vegg utvendig – stående bord",
      "Tekst2": null,
      "Kode": "QK2.11xx---",
      "Delalternativer": null
    }, {
      "Siffer": "22",
      "Tekst": "Bordkledning på vegg utvendig – stående ukantede bord",
      "Tekst2": null,
      "Kode": "QK2.12x---",
      "Delalternativer": null
    }, {
      "Siffer": "23",
      "Tekst": "Bordkledning på vegg utvendig – stående spaltekledning",
      "Tekst2": null,
      "Kode": "QK2.15xx---",
      "Delalternativer": null
    }, {
      "Siffer": "24",
      "Tekst": "Bordkledning på vegg utvendig - liggende bord",
      "Tekst2": null,
      "Kode": "QK2.21xx---",
      "Delalternativer": null
    }, {
      "Siffer": "26",
      "Tekst": "Platekledning på vertikal flate utvendig utvendig",
      "Tekst2": null,
      "Kode": "QK5.226--",
      "Delalternativer": null
    }, {
      "Siffer": "31",
      "Tekst": "Kledning med tynnplatekassetter av kopper",
      "Tekst2": null,
      "Kode": "SM4.2--",
      "Delalternativer": null
    }, {
      "Siffer": "32",
      "Tekst": "Kledning med tynnplatekassetter av titansink",
      "Tekst2": null,
      "Kode": "SM4.3--",
      "Delalternativer": null
    }, {
      "Siffer": "33",
      "Tekst": "Kledning med tynnplatekassetter av aluminium",
      "Tekst2": null,
      "Kode": "SM4.4--",
      "Delalternativer": null
    }, {
      "Siffer": "34",
      "Tekst": "Kledning med tynnplatekassetter av varmforsinket stål",
      "Tekst2": null,
      "Kode": "SM4.5--",
      "Delalternativer": null
    }, {
      "Siffer": "35",
      "Tekst": "Kledning med plane metallplater",
      "Tekst2": null,
      "Kode": "SM5.1",
      "Delalternativer": null
    }, {
      "Siffer": "88",
      "Tekst": "Uten utvendig kledning",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }, {
      "Siffer": "99",
      "Tekst": "Annen utvendig kledning – må spesifiseres",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }],
    "selected": {
      "Siffer": "99",
      "Tekst": "Annen utvendig kledning – må spesifiseres",
      "Tekst2": null,
      "Kode": null,
      "Delalternativer": null
    }
  };
$scope.t.selected = $scope.t.Valgalternativer[0];
})
.filter('matriseValgFilter', function() {
	
    return function (option) {

        if (!isNaN(option.Siffer) && option.Kode != null){
        	return option.Siffer + ' - ' + option.Tekst + ' (' + option.Kode + ')';
        }
        
        if (!isNaN(option.Siffer)){
        	return option.Siffer + ' - ' + option.Tekst;
        }
        
        return option.Tekst;
    
    
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.4.0/animate.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular-animate.min.js"></script>

<body ng-app="app">
  <div ng-controller="controller as c" style="padding:10px;">

    <select class="form-control" 
        ng-model="t.selected" 
        ng-options="option | matriseValgFilter for option in t.Valgalternativer" >
    </select>

<pre style="margin-top: 10px;">
{{t.selected | json}}
</pre>

  </div>

</body>

Обновлено

О, я понимаю. Вы определяете t.selected в своей переменной t. Но это не работает, потому что

{
  "Siffer": "99",
  "Tekst": "Annen utvendig kledning – må spesifiseres",
  "Tekst2": null,
  "Kode": null,
  "Delalternativer": null
}!= {
  "Siffer": "99",
  "Tekst": "Annen utvendig kledning – må spesifiseres",
  "Tekst2": null,
  "Kode": null,
  "Delalternativer": null
}

Другое слово не равны.

$scope.t.Valgalternativer[$scope.t.Valgalternativer.length-1]!=$scope.t.selected

Попробуй это

$scope.t.selected = .Valgalternativer[$scope.t.Valgalternativer.length-1];
person Stepan Kasyanenko    schedule 11.02.2016
comment
Ну, это изменяет t.select на неправильное значение. Теперь вы сбрасываете его на первый элемент Valgalternativer[0] ({Matrise BE3.2:1}), но уже выбрано значение 99. - person ganjan; 11.02.2016
comment
Как вы думаете, почему выбрано значение 99? В jsfiddle в {{t.selected | json}} также показан первый элемент {Matrise BE3.2:1}). - person Stepan Kasyanenko; 11.02.2016
comment
Нет, это не так, ‹pre› показывает 99 - Annen utvendig kledning – må specifiseres. Если вы не измените его на первый элемент с помощью ng-init, как вы это делаете. Если вы посмотрите на $scope.t.selected, значение равно 99 — Annen utvendig kledning — må specifiseres. Я не хочу, чтобы это менялось при загрузке. - person ganjan; 11.02.2016

изменить

Согласно вашему комментарию, чтобы это сработало, один из способов - установить выбранное свойство следующим образом.

$scope.t.selected =$scope.t.Valgalternativer[2];

Если объект поступает из другой службы или json, возможно, вам придется найти или отфильтровать его из t.Valgalternativer, а затем назначить соответствующий индекс.

Это связано с тем, что, как указано в другом ответе, если вы инициализируете выбранный так, как вы это делаете, это будет новый объект, хэш-значение которого отличается.

Если вам нравится такой подход, удалите свойство "selected" из t и добавьте его отдельно, как указано выше. Никакую разметку менять не нужно.

начальный

Попробуй это

<select class="form-control" 
    ng-model="t.selected" 
    ng-options="option | matriseValgFilter as option | matriseValgFilter for option in t.Valgalternativer" 
    ng-change="change(t.selected)"
    ng-init='t.selected = "99 - Annen utvendig kledning – må spesifiseres"'>
</select>

ViewValue выбранной вами опции должно совпадать со значением одной из опций select.

Синтаксис as используется для установки значений опций в select. Документация здесь.

person Naga Sandeep    schedule 11.02.2016
comment
Что ж, значение при загрузке не всегда равно 99 или первому значению в массиве, $scope.t.Valgalternativer[0]. Это должно быть текущее значение t.selected, уже определенное в области видимости. - person ganjan; 11.02.2016
comment
@ganjan исправил ответ в соответствии с вашим комментарием. - person Naga Sandeep; 11.02.2016

Ни один из ответов не работал должным образом в моем реальном приложении, но решил его с помощью метода в контроллере, который я вызываю с помощью ng-init.

Закончилось этим:

    <select class="form-control"  
            ng-init="loadMatriseValg(node, t)"
            ng-model="t.selected"
            ng-options="option | matriseValgFilter for option in t.Valgalternativer"
            ng-change="changeMatrise(node, t.selected, '{{t.selected.Kode}}')"></select>

Затем в контроллере у меня есть это:

            $scope.loadMatriseValg = function (node, t) {

                // user has not selected anything, set default value
                if (!t.selected) {
                    t.selected = t.Valgalternativer[0];
                }

                // loop through all valg alternativer
                for (var v = 0; v < t.Valgalternativer.length; v++) {

                    if (t.Valgalternativer[v].Siffer == t.selected.Siffer) {

                        t.selected = t.Valgalternativer[v];
                        return;
                    }
                }

            }

Новая скрипка здесь:

https://jsfiddle.net/fiddlejan/wng2genw/

person ganjan    schedule 12.02.2016