2013-07-10 66 views
7

我在我的AngularJS應用程序中使用select2插件來顯示一些實體(標籤)的列表。這是我的模板的一部分:在AngularJS應用程序中使用select2插件

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

,這是我的範圍代碼的一部分:

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

我想提供快速添加新的標籤,如果在標籤列表是不存在它的能力。因此,我重寫了formatNoMatches select2選項以顯示「添加新標記」鏈接。我應該如何正確地將$ scope的addTag()函數綁定到鏈接的點擊事件?

+0

你可以在範圍內添加它.. 即。 $範圍。addTag = function(){ } – insomiac

+0

我一直在爲同一個問題奮鬥了很多天。我覺得角度需要被告知我們正在製作的標籤。但我無法弄清楚如何。 – Manu

回答

4

你可以參考這個:

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; 
     } 
    }; 



}; 

工作小提琴: Quickly add a new tag

+0

工作小提琴在Chrome中不工作29.未捕獲的錯誤:沒有模塊:ui.select2 – TheSharpieOne

+0

解決方案的問題(實際上是原始問題)是「創建」按鈕仍然超出了Angular的摘要循環,而新添加的項目仍然未知角度。 – Manu

+0

小提琴不起作用,因爲對select2庫的引用已損壞。這是一個原始的GitHub引用,其中包含jsFiddle不允許的MIME類型的text/plain。 –

6

這個問題的解決方案的關鍵是你必須使用$ compile服務在選項對象中的formatNoMatches函數返回的HTML上。這個編譯步驟會將標記中的ng-click指令連接到範圍。不幸的是,說起來容易做起來難。

您可以在這裏看到完整的工作示例:http://jsfiddle.net/jLD42/4/

沒有辦法,我知道了AngularJS觀看選擇2控制監視搜索的結果,所以我們必須通知控制器時,沒有找到結果。這是很容易通過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; 
    } 
}; 

$scope.noResultsTag財產跟蹤由沒有相匹配的用戶最後輸入的值。使用$ scope封裝更新到$scope.noResultsTag。$ apply是必需的,因爲在AngularJS摘要循環的上下文之外調用formatNoMatches

能看$scope.noResultsTag和編譯formatNoMatches標記發生更改時:

$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); 

你可能想知道什麼$超時做什麼。它用於避免更新DOM的select2控件與formatNoMatches標記之間的爭用條件以及試圖編譯該標記的監視函數。否則,$('.select2-no-results')選擇器很有可能找不到它正在查找的內容,編譯步驟將不會編譯任何內容。

編譯完add tag鏈接後,ng-click指令將能夠調用控制器上的addTag函數。你可以在jsFiddle中看到這個動作。點擊添加標籤鏈接將使用您在select2控件中輸入的搜索詞更新標籤數組,並且您將能夠在下次向select2控件中輸入新搜索詞時在標記和選項列表中看到它。

+0

似乎運作良好。我一直在努力解決這個問題。謝謝! –

相關問題