web-dev-qa-db-fra.com

AngularJs: Comment faire ui-select fonctionner correctement?

LA SITUATION:

Je crée une application angulaire sur laquelle je dois utiliser ui-select: dans la page d'informations de l'utilisateur, dans la sélection, il doit être possible de choisir un ou plusieurs tags. Cela fonctionne presque, sauf que j'ai des problèmes pour obtenir et afficher les balises préexistantes.

LE CODE:

Vue:

<ui-select multiple ng-model="info_data.tags" theme="bootstrap" ng-disabled="disabled">

  <ui-select-match placeholder="Select tag...">{{$item.name}} </ui-select-match>

  <ui-select-choices repeat="tag in all_tags | propsFilter: {name: $select.search}">

    {{tag.name}}

  </ui-select-choices>

</ui-select>

<p>Selected: {{info_data.tags}}</p>

Manette:

$http({

    url: base_url + 'main/db_get_all_tags',
    method: "POST",

 }).success(function (data) {

    $scope.all_tags = data;

});

$scope.show_info = function() {

    var result_info = DbService.get_info( $stateParams.db_data_id );

    result_info.then( function( data )
    {
        $scope.info_data = data;

    });

};

TENTATIVE 1:

Il se produit un comportement très étrange. Je ne vois pas les balises dans la page d’information de l’utilisateur, ni même dans la sélection d’interface utilisateur. Sauf en cas d'actualisation 5/6 fois, cela fonctionnera comme par magie, en affichant les balises dans la page d'informations utilisateur et dans la sélection ui. Dans les deux cas, travaillant et non, j'obtiens plusieurs messages d'erreur du même genre:

Impossible de lire la propriété 'longueur' de non définie.

TENTATIVE 2:

Afin de résoudre ce problème, j'ai ajouté ce code dans le contrôleur:

$scope.info_data = { tags: [] };
$scope. all_tags = [];

Et je ne reçois plus aucun message d'erreur. L'application est stable et je peux voir les balises appropriées dans la page d'informations utilisateur. Le seul problème est que les tags ne sont plus chargés dans la sélection d'iu.

Si je sélectionne une nouvelle balise, alors cela fonctionne bien, mais je perds les balises préexistantes.

Des questions):

Comment puis-je faire fonctionner correctement Ui-select? (actuellement v0.8.3) Il y a un problème de conflit?

Comment puis-je appeler correctement des données préexistantes à partir du serveur?

Merci beaucoup!

8
FrancescoMussi

Vous n'avez pas été particulièrement descriptif des erreurs que vous constatez, je ne sais donc pas si ce qui suit aidera. 

J'ai eu un problème à l'origine lorsque le code de démonstration ui-select a été utilisé à titre d'exemple, car ils utilisent le filtre propsFilter qui est un filtre personnalisé qu'ils ont écrit pour la démonstration:

<ui-select-choices repeat="tag in all_tags | propsFilter: {name: $select.search}">

Je suppose que vous n'incluez pas ce filtre dans votre code, ce qui peut expliquer en partie votre problème. Vous pouvez le résoudre en utilisant normal filter :

<ui-select-choices repeat="tag in all_tags | filter: {name: $select.search}">

Si vous avez plusieurs propriétés à filtrer, vous pouvez également écrire le filtre propsFilter à filtrer sur OR plutôt que sur AND. Si vous utilisez 'filter' pour filtrer plusieurs propriétés, il essaiera de faire correspondre la valeur de recherche à toutes les propriétés.

app.filter('propsFilter', function() {
  return function(items, props) {
            var out = [];
                if (angular.isArray(items)) {
                  items.forEach(function(item) {
                        var itemMatches = false;

                        var keys = Object.keys(props);
                        for (var i = 0; i < keys.length; i++) {
                              var prop = keys[i];
                              var text = props[prop].toLowerCase();
                              if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
                                    itemMatches = true;
                                    break;
                                  }
                            }

                            if (itemMatches) {
                              out.Push(item);
                            }
                      });
                } else {
                  // Let the output be the input untouched
                      out = items;
                }

                return out;
          };
    });

vous pouvez voir le commit avec le filtre ici: https://github.com/angular-ui/ui-select/commit/3fac88cfad0ad2369c567142eadba52bdb7998b1

Bien que, si vous avez des exigences de filtrage spécifiques, je vous recommanderais d'écrire votre propre filtre pour garantir des performances optimales.

35
Nick Martin

Je ne sais pas à quoi ressemblait la situation avant Select2 # 4.0, mais ce n'est vraiment pas si difficile de l'utiliser sans angular-ui-select (et c'est une dépendance de moins)

Incluez simplement select2 dans vos dépendances bower et utilisez-le dans votre fonction link dans la directive:

.directive('someDirective', function() {
    return {
        restrict: 'E',
        link: function(scope, element, attrs) {
            element.find('.your-select2').select2({
                theme: 'classic',
                placeholder: 'Select a placeholder...',
                allowClear: true,
                data: [{ id: 'New', text: 'New'}]...
            });
        },
    };
})

et votre HTML:

<select class="your-select2" ng-model="a.model.field"></select>

Vous pouvez également charger la data à partir du contrôleur via un service si vous le souhaitez, puis utilisez simplement la scope pour la définir!

Je dis cela car j'ai essayé d'utiliser angular-ui-select parce que je me suis dit "hé c'est angulaire, vous devez utiliser un plugin pour cela!", Mais ce n'est pas toujours le cas :). De plus, j’ai trouvé la documentation peu utile (appelez-moi paresseux mais bon)

3
a7omiton