2013-07-10 12 views
7

Używam wtyczki select2 w mojej aplikacji AngularJS do wyświetlania listy niektórych encji (znaczników). To jest mój szablon jest częścią:Użyj wtyczki select2 w aplikacji AngularJS

select.ddlTags(ui-select2="select2Options", multiple, ng-model="link.tags") 
     option(ng-repeat="tag in tags", value="{{tag.id}}") {{tag.name}} 

i to jest część mojego kodu oscyloskopu:

$scope.select2Options = { 
    formatNoMatches: function(term) { 
    var message = '<a ng-click="addTag()">Добавить тэг "' + term + '"</a>' 
    console.log(message); 
    return message; 
    } 
} 

Chcę zapewnić możliwość szybkiego dodania nowego tag jeśli nie występuje na liście tagów. Tak więc przesłonię opcję formatNoMatches select2, aby wyświetlić link "dodaj nowy tag". Jak powinienem poprawnie powiązać funkcję addTag() z $ scope z kliknięciem łącza?

+0

możesz dodać go w zakresie .. tj. $ scope.addTag = function() { } – insomiac

+0

Od wielu lat walczę z tymi samymi problemami. Mam wrażenie, że kątowy musi być mówiony o znaczniku , który robimy. Ale nie mogę zrozumieć, jak. – Manu

Odpowiedz

4

Można odnieść to:

HTML

<div ng-controller="MyCtrl"> 
     <input ng-change="showDialog(tagsSelections)" type="text" ui-select2="tagAllOptions" ng-model="tagsSelections" style="width:300px;" /> 
     <pre> tagsSelection: {{tagsSelections | json}}</pre>   
</div> 

JS

var myApp = angular.module('myApp', ['ui.select2']); 

function MyCtrl($scope, $timeout) { 

    // Initialize with Objects. 
    $scope.tagsSelection = [{ 
     "id": "01", 
      "text": "Perl" 
    }, { 
     "id": "03", 
      "text": "JavaScript" 
    }]; 

    $scope.showDialog = function (item) { 
     console.log(item); // if you want you can put your some logic. 
    }; 

    $timeout(function() { 
     $scope.tagsSelection.push({ 
      'id': '02', 
       'text': 'Java' 
     }); 
    }, 3000); 

    $scope.tagData = [{ 
     "id": "01", 
      "text": "Perl" 
    }, { 
     "id": "02", 
      "text": "Java" 
    }, { 
     "id": "03", 
      "text": "JavaScript" 
    }, { 
     "id": "04", 
      "text": "Scala" 
    }]; 

    // to show some add item in good format 
    $scope.formatResult = function (data) { 
     var markup; 
     if (data.n === "new") markup = "<div> <button class='btn-success btn-margin'><i class='icon-plus icon-white'></i> Create :" + data.text + "</button></div>"; 
     else markup = "<div>" + data.text + "</div>"; 
     return markup; 

    }; 

    $scope.formatSelection = function (data) { 
     return "<b>" + data.text + "</b></div>"; 
    }; 

    $scope.tagAllOptions = { 
     multiple: true, 
     data: $scope.tagData, 
     tokenSeparators: [","], 
     createSearchChoice: function (term, data) { // this will create extra tags. 
      if ($(data).filter(function() { 
       return this.v.localeCompare(term) === 0; 
      }).length === 0) { 
       return { 
        id: term, 
        text: term, 
        n: "new", 
        s: "" 
       }; 
      } 
     }, 
     // initSelection: function(element, callback) { //if you want to set existing tags into select2 
    // callback($(element).data('$ngModelController').$modelValue); 
    // }, 
     formatResult: $scope.formatResult, 
     formatSelection: $scope.formatSelection, 
     dropdownCssClass: "bigdrop", 
     escapeMarkup: function (m) { 
      return m; 
     } 
    }; 



}; 

pracujących Fiddle: Quickly add a new tag

+0

Praca Fiddle nie działa w Chrome 29. Uncaught Error: No module: ui.select2 – TheSharpieOne

+0

Problem z rozwiązaniem (które w rzeczywistości jest oryginalnym problemem) polega na tym, że przycisk "Utwórz" nadal znajduje się poza cyklem trawienia Angulara i nowo dodany przedmiot pozostaje nieznany kątowi. – Manu

+0

Fiddle nie działa, ponieważ odwołanie do biblioteki select2 jest zepsute. Jest to surowe odniesienie do GitHub z tekstem/zwykłym typem MIME, które nie jest dozwolone przez jsFiddle. –

6

Kluczem do rozwiązania tego problemu jest to, że ciebie Muszę użyć usługi $ compile na HTML zwróconym przez funkcję formatNoMatches w obiekcie opcji. Ten krok kompilacji spowoduje powiązanie dyrektywy ng-click w znacznikach z zakresem. Niestety, jest to nieco łatwiej powiedzieć niż zrobić.

Można zobaczyć pełną przykład pracuje tu: http://jsfiddle.net/jLD42/4/

Nie ma mowy o tym nie wiem za angularjs obserwować kontrolę select2 monitorowania wyników wyszukiwania, więc musimy poinformować sterownika Po nie znaleziono wyników. Łatwo to zrobić za pomocą funkcji formatNoMatches:

$scope.select2Options = { 
    formatNoMatches: function(term) { 
     console.log("Term: " + term); 
     var message = '<a ng-click="addTag()">Add tag:"' + term + '"</a>'; 
     if(!$scope.$$phase) { 
      $scope.$apply(function() { 
       $scope.noResultsTag = term; 
      }); 
     } 
     return message; 
    } 
}; 

Obiekt $scope.noResultsTag śledzi ostatniej wartości wprowadzonej przez użytkownika, który nie przyniosło wyników. Zawieszenie aktualizacji do $scope.noResultsTag z $ scope. $ Apply jest konieczne, ponieważ formatNoMatches jest wywoływany poza kontekstem pętli podsumowania AngularJS.

Możemy oglądać $scope.noResultsTag i skompilować znaczników formatNoMatches razie wystąpienia zmian:

$scope.$watch('noResultsTag', function(newVal, oldVal) { 
    if(newVal && newVal !== oldVal) { 
     $timeout(function() { 
      var noResultsLink = $('.select2-no-results'); 
      console.log(noResultsLink.contents()); 
      $compile(noResultsLink.contents())($scope); 
     }); 
    } 
}, true); 

Można się zastanawiać, co $ timeout tam robi. Jest używany do uniknięcia sytuacji wyścigowej pomiędzy kontrolką select2 aktualizującą DOM a znacznikiem formatNoMatches, a funkcją watch próbuje skompilować ten znacznik. W przeciwnym razie istnieje duża szansa, że ​​selektor $('.select2-no-results') nie znajdzie tego, czego szuka, a krok kompilacji nie będzie miał nic do skompilowania.

Po utworzeniu łącza dodawania tagu, dyrektywa ng-click będzie mogła wywołać funkcję addTag na kontrolerze. Możesz to zobaczyć w akcji w jsFiddle. Kliknięcie linku Dodaj tag spowoduje aktualizację tablicy Znaczniki z wyszukiwanym terminem wprowadzonym do kontrolki select2, a będziesz mógł zobaczyć to w znacznikach i liście opcji, gdy następnym razem wprowadzisz nowe wyszukiwane hasło do kontrolki select2.

+0

Wydaje się działać dobrze. Zmagałem się z tym problemem. Dzięki! –

Powiązane problemy