Inizializzazione selezionare con AngularJS e ng-repeat


133

Sto cercando di ottenere la casella di selezione per iniziare con un'opzione pre-riempita utilizzando ng-repeat con AngularJS 1.1.5. Invece la selezione inizia sempre con niente selezionato. Ha anche un'opzione vuota, che non voglio. Penso che ci sia un effetto collaterale di non essere selezionato nulla.

Posso farlo funzionare usando ng-options invece di ng-repeat, ma voglio usare ng-repeat per questo caso. Sebbene il mio esempio ristretto non lo mostri, voglio anche impostare l'attributo title di ciascuna opzione e non c'è modo di farlo usando ng-options, per quanto ne so.

Non penso che questo sia legato al comune ambito di AngularJs / problema ereditario prototipico. Almeno non vedo nulla di ovvio quando ispeziono a Batarang. Inoltre, quando si seleziona un'opzione nella selezione con l'interfaccia utente, il modello si aggiorna correttamente.

Ecco l'HTML:

<body ng-app ng-controller="AppCtrl">
    <div>
        Operator is: {{filterCondition.operator}}
    </div>
    <select ng-model="filterCondition.operator">
       <option 
           ng-repeat="operator in operators" 
           value="{{operator.value}}"
       >
           {{operator.displayName}}
       </option>
    </select>
</body>

E il JavaScript:

function AppCtrl($scope) {

    $scope.filterCondition={
        operator: 'eq'
    }

    $scope.operators = [
        {value: 'eq', displayName: 'equals'},
        {value: 'neq', displayName: 'not equal'}
     ]
}

JS Fiddle per questo: http://jsfiddle.net/coverbeck/FxM3B/2/


1
ngOption è stato creato perché non esisteva un modo pulito per farlo con ngRepeat. ngRipeti si svolge dopo che l'opzione è stata selezionata. Hai provato a impostare ngSeleziona le tue opzioni
TheSharpieOne il

Sì! Il ngSelected ha funzionato! Pubblicherò un JsFiddle funzionante aggiornato.
Charles O.

Va notato che in AngualrJS 1.2 questo codice funziona in modo diverso - Non crea un nuovo elemento <OPTION> vuoto, tuttavia, è solo in grado di selezionare la prima opzione nella casella di riepilogo. Puoi vederlo qui
VitalyB,

Risposte:


226

OK. Se non si desidera utilizzare il modo corretto ng-options, è possibile aggiungere un ng-selectedattributo con una logica di controllo delle condizioni affinché la optiondirettiva possa far funzionare la preselezione.

<select ng-model="filterCondition.operator">
    <option ng-selected="{{operator.value == filterCondition.operator}}"
            ng-repeat="operator in operators"
            value="{{operator.value}}">
      {{operator.displayName}}
    </option>
</select>

Working Demo


37
Ti darò il merito dato che l'hai capito da solo e hai fatto l'esempio completo. Anche se non sono d'accordo con il tuo commento sul fatto che ng-options sia il "modo corretto". :) Ho sempre usato ng-options da solo, ma questo ha richiesto di fare qualcosa che ng-options non supporta, per quanto piccolo. E il documento angolare dice che puoi anche jg-repeat. Grazie, Charles
Charles O.

Grazie, è stato un modo semplice per disabilitare alcune opzioni.
Dorian,

11
ng-options è corretta solo se le sue custodie si adattano alle tue. Potresti aver bisogno di attributi / classi extra nei campi opzione / optgroup ecc.
mystrdat,

6
"il modo corretto" a volte non funziona (ad es. se si desidera tradurre le stringhe che popolano i nomi delle opzioni)
btk

11
Penso che l'espressione ng-selezionata debba essere senza {{}}: ng-selected = "operator.value == filterCondition.operator"
mvermand,

35

Per il tag select, angular fornisce la direttiva ng-options. Ti dà il quadro specifico per impostare le opzioni e impostare un valore predefinito. Ecco il violino aggiornato usando ng-options che funziona come previsto: http://jsfiddle.net/FxM3B/4/

HTML aggiornato (il codice rimane lo stesso)

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.value as operator.displayName for operator in operators">
</select>
</body>

3
Ciao Jeremy - Sto provando a farlo senza ng-opzioni. Come ho detto nella mia domanda e in risposta a Shaun, vorrei impostare l'attributo title su ciascuna opzione e non posso farlo con ng-options, per quanto ne so. Grazie, Charles
Charles O.

9

Grazie a TheSharpieOne per aver sottolineato l'opzione ng-selezionata. Se quello fosse stato pubblicato come una risposta piuttosto che come un commento, avrei fatto quella risposta corretta.

Ecco un JSFiddle funzionante: http://jsfiddle.net/coverbeck/FxM3B/5/ .

Ho anche aggiornato il violino per usare l'attributo title, che avevo tralasciato nel mio post originale, poiché non era la causa del problema (ma è la ragione per cui voglio usare ng-repeat invece di ng-options) .

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator">
   <option ng-repeat="operator in operators" title="{{operator.title}}" ng-selected="{{operator.value == filterCondition.operator}}" value="{{operator.value}}">{{operator.displayName}}</option>
</select>
</body>

JS:

function AppCtrl($scope) {

    $scope.filterCondition={
        operator: 'eq'
    }

    $scope.operators = [
        {value: 'eq', displayName: 'equals', title: 'The equals operator does blah, blah'},
        {value: 'neq', displayName: 'not equal', title: 'The not equals operator does yada yada'}
     ]
}

Mi dispiace per la pubblicazione come commento. Non avevo voglia di fare un esempio e non ero sicuro al 100% che avrebbe funzionato. Era solo un sospetto.
TheSharpieOne,

9

Il fatto che angolare stia iniettando un elemento opzione vuoto nella selezione è che l'oggetto modello associato ad esso di default viene fornito con un valore vuoto quando inizializzato.

Se si desidera selezionare un'opzione predefinita, probabilmente è possibile impostarla sull'ambito nel controller

$scope.filterCondition.operator = "your value here";

Se vuoi un segnaposto di opzione vuoto, questo funziona per me

<select ng-model="filterCondition.operator" ng-options="operator.id as operator.name for operator in operators">
  <option value="">Choose Operator</option>
</select>

2
Questo è buono, ma Angular crea un'opzione vuota. Come evitarlo?
MarceloBarbosa,

1

Come suggerito, è necessario utilizzare ng-options e sfortunatamente credo che sia necessario fare riferimento all'elemento array per impostazione predefinita (a meno che l'array non sia un array di stringhe).

http://jsfiddle.net/FxM3B/3/

JavaScript:

function AppCtrl($scope) {


    $scope.operators = [
        {value: 'eq', displayName: 'equals'},
        {value: 'neq', displayName: 'not equal'}
     ]

    $scope.filterCondition={
        operator: $scope.operators[0]
    }
}

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator.value}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.displayName for operator in operators">
</select>
</body>

Sai perché e ne sei sicuro? La documentazione ( docs.angularjs.org/api/ng.directive:select ) afferma che è necessario utilizzare ng-options solo quando si esegue il binding a un valore non stringa. Come ho detto, voglio usare l'attributo title e non c'è modo di farlo con ng-options. Qualcosa come <option title = "Una descrizione molto lunga di questa scelta" ...> Grazie.
Charles O.

Credo che la nota nei documenti sia un po 'poco chiara e in realtà significa che dovresti usare una stringa per il modello e avere una serie di stringhe per le opzioni. Se non ti dispiace qual è il ragionamento per l'utilizzo dell'attributo "title" non lo vedo su W3C w3schools.com/tags/tag_option.asp e non ricordo di averlo usato davvero. Non potresti semplicemente archiviare la descrizione negli oggetti e poi ancora recuperare quei dati poiché è a questo che il modello è ora associato?
Shaunhusain,

Nella pagina W3C a cui sei collegato, se fai clic sul link Attributi globali, vedrai che l'attributo title è supportato dall'elemento opzione. Sto usando l'attributo title solo per visualizzare il testo "tooltip", in modo che se passi con il mouse su un'opzione, puoi ottenere una descrizione più ampia di cosa significhi l'opzione. È una cosa piccola, ma sarebbe bello avere, se possibile.
Charles O.

@CharlesO. Voglio fare esattamente come te. Impostare un oggetto (valore non stringa) ma voglio anche usare un titolo nell'elenco delle opzioni. C'è una soluzione per questo. Non riesco a trovarlo ...
Wilt,

1

Se stai usando md-select e ng-repeat in md-option da materiale angolare, puoi aggiungere ng-model-options="{trackBy: '$value.id'}"al tag md-select ash mostrato in questa penna

Codice:

<md-select ng-model="user" style="min-width: 200px;" ng-model-options="{trackBy: '$value.id'}">
  <md-select-label>{{ user ? user.name : 'Assign to user' }}</md-select-label>
  <md-option ng-value="user" ng-repeat="user in users">{{user.name}}</md-option>
</md-select>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.