2015-11-20 32 views
2

我正在使用兩個下拉菜單(在此演示中爲食品類別和特定項目)以角度形式構建標籤管理器。當用戶選擇一個食物類別時,應該顯示項目下拉菜單,當該下拉菜單中有一個值被選中時,我想要一個字符串以':'的格式添加到我的標籤列表中。下面是代碼:使用ng-options添加額外/默認選項

app.js

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

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

    $scope.tags = []; 
    $scope.userCategory; 
    $scope.userFood; 
    $scope.primaryFoods = [ 
    { 
     'id': 1, 
     'parent_id': null, 
     'name': 'Pizza' 
    }, 
    { 
     'id': 4, 
     'parent_id': null, 
     'name': 'Burgers' 
    }, 
    { 
     'id': 7, 
     'parent_id': null, 
     'name': 'Pasta' 
    }, 
    ]; 
    $scope.secondaryFoods = [ 
    { 
     'id': 2, 
     'parent_id': 1, 
     'name': 'Cheese Pizza' 
    }, 
    { 
     'id': 3, 
     'parent_id': 1, 
     'name': 'Combo Pizza' 
    }, 
    { 
     'id': 5, 
     'parent_id': 4, 
     'name': 'Cheese Burgers' 
    }, 
    { 
     'id': 6, 
     'parent_id': 4, 
     'name': 'Hamburgers' 
    }, 
    ]; 

}); 

app.directive('doubleTagManager', function() { 
    return { 
    restrict: 'E', 
    scope: {tags: '=', primary: '=', secondary: '=', userPrimary: '=', userSecondary: '='}, 
    templateUrl: 'double-tag-manager.html', 
    link: function ($scope, $element) { 
     var input = angular.element($element.find('select')[1]); 
     // This adds the new tag to the tags array in '<Primary>: <Secondary>' format 
     $scope.add = function() { 
     var new_value = input[0].value; 
     if ($scope.tags.indexOf(new_value) < 0) { 
      $scope.tags.push($scope.userPrimary.name + ': ' + $scope.userSecondary.name); 
     } 
     }; 
     // This is the ng-click handler to remove an item 
     $scope.remove = function (idx) { 
      $scope.tags.splice(idx, 1); 
     }; 
     input.bind('change', function (event) { 
     $scope.$apply($scope.add); 
     }); 
    } 
    }; 
}); 

雙標籤manager.html

<div class="row"> 
    <div class="col-md-6"> 
    <select name="uFoodsPrimary" id="foodPrimary" class="form-control" 
      ng-model="userPrimary" 
      ng-options="item.name for item in primary track by item.name" required> 
     <option value="">Select a Food category!</option> 
    </select> 
    </div> 
    <div class="col-md-6" ng-show="userPrimary"> 
    <select name="uFoodsSecondary" id="foodSecondary" class="form-control" 
      ng-model="userSecondary" 
      ng-options="item.name for item in (secondary | filter: {parent_id: userPrimary.id}) 
      track by item.name" 
      required> 
     <option value="">Select a Food sub-category!</option> 
    </select> 
    </div> 
</div> 
<div class="tags"> 
    <a ng-repeat="(idx, tag) in tags" class="tag" ng-click="remove(idx)">{{tag}}</a> 
</div> 

我想補充的是,選擇「所有的食物」,使用戶的能力不需要單獨選擇所有的項目,但我似乎無法弄清楚如何使用ng-options來添加額外的字段。

Fiddle

獎金:如果選擇一個類別沒有孩子,我想將其添加到標籤列表默認。

回答

1

Erik, 這裏是修改的代碼來實現您的所有選擇功能。此外,您可以進一步增強它,以實現您的使用案例BONUS。我想建議使用現有的angularui-select2組件。它還有很多其他選項。它會讓你的生活更輕鬆。

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

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

 
    $scope.tags = []; 
 
    $scope.sub_cat_show = false; 
 
    $scope.all_sub_cat_show = false; 
 
    $scope.userCategory; 
 
    $scope.userFood; 
 
    $scope.primaryFoods = [{ 
 
    'id': 0, 
 
    'parent_id': null, 
 
    'name': 'All Foods' 
 
    }, { 
 
    'id': 1, 
 
    'parent_id': null, 
 
    'name': 'Pizza' 
 
    }, { 
 
    'id': 4, 
 
    'parent_id': null, 
 
    'name': 'Burgers' 
 
    }, { 
 
    'id': 7, 
 
    'parent_id': null, 
 
    'name': 'Pasta' 
 
    }]; 
 
    $scope.secondaryFoods = [ 
 
    { 
 
    'id': 2, 
 
    'parent_id': 1, 
 
    'name': 'Cheese Pizza' 
 
    }, { 
 
    'id': 3, 
 
    'parent_id': 1, 
 
    'name': 'Combo Pizza' 
 
    }, { 
 
    'id': 5, 
 
    'parent_id': 4, 
 
    'name': 'Cheese Burgers' 
 
    }, { 
 
    'id': 6, 
 
    'parent_id': 4, 
 
    'name': 'Hamburgers' 
 
    }, ]; 
 

 
}); 
 

 
app.directive('doubleTagManager', function() { 
 
    return { 
 
    restrict: 'E', 
 
    scope: { 
 
     tags: '=', 
 
     primary: '=', 
 
     secondary: '=', 
 
     userPrimary: '=', 
 
     userSecondary: '=', 
 
     sub_cat_show: '=', 
 
     'all_sub_cat_show': '=' 
 
    }, 
 
    template: "<div class='row'><div class='col-md-6'><select ng-change='primaryChange()' name='uFoodsPrimary' id='foodPrimary' class='form-control' ng-model='userPrimary' ng-options='item.name for item in primary track by item.name' required> <option value=''>Select a Food category!</option></select></div><div ng-show='sub_cat_show' class='col-md-6'><select ng-show='all_sub_cat_show' ng-change='secondaryChange()' name='uFoodsSecondary' id='foodSecondary' class='form-control' ng-model='userSecondary'" + 
 
     //options code 
 
     "ng-options='item.name for item in (secondary | filter: {parent_id: userPrimary.id}) track by item.name' required>" + 
 
     //end options code 
 
     "<option value=''>Select a Food sub-category!</option></select> <select ng-show='!all_sub_cat_show'><option value=''>Food all sub-category</option></select> </div></div><div><a ng-repeat='(idx, tag) in tags' class='tag' ng-click='remove(idx)'>{{tag}}</a></div>", 
 
    link: function($scope, $element) { 
 
     var primarySel = angular.element($element.find('select')[0]); 
 
     var secondarySel = angular.element($element.find('select')[1]); 
 
     // This adds the new tag to the tags array in '<Primary>: <Secondary>' format 
 

 
     $scope.primaryChange = function() { 
 
     $scope.tags = []; // reset 
 
     $scope.sub_cat_show = primarySel[0].value?true:false; 
 
     if (primarySel[0].value == 'All Foods') 
 
     { 
 
      $scope.all_sub_cat_show = false; 
 
      angular.forEach($scope.primary, function(primary, index) { 
 
      angular.forEach($scope.secondary, function(secondary, index) { 
 
       if(secondary.parent_id==primary.id) 
 
        $scope.tags.push(primary.name + ': ' + secondary.name); 
 
      }); 
 
      }); 
 
     } 
 
     
 
     else 
 
     { 
 
      $scope.all_sub_cat_show = true; 
 
     } 
 
     } 
 
     
 
     $scope.secondaryChange = function() { 
 
      var new_value = secondarySel[0].value; 
 
      if ($scope.tags.indexOf(new_value) < 0) { 
 
      $scope.tags.push(primarySel[0].value + ': ' + new_value); 
 
      } 
 
     }; 
 
     // This is the ng-click handler to remove an item 
 
     $scope.remove = function(idx) { 
 
     $scope.tags.splice(idx, 1); 
 
     }; 
 
    } 
 
    }; 
 
});
<script src="https://code.angularjs.org/1.4.3/angular-animate.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script> 
 
<!DOCTYPE html> 
 
<html > 
 

 
<head> 
 
    <meta charset="utf-8" /> 
 
    <title>AngularJS Demo</title> 
 
    <script> 
 
    document.write('<base href="' + document.location + '" />'); 
 
    </script> 
 
</head> 
 

 
<body> 
 
    <div ng-app="myApp" ng-controller="myCtrl"> 
 
    <double-tag-manager tags="tags" primary="primaryFoods" secondary="secondaryFoods" user-primary="userCategory" user-secondary="userFood"> 
 
    </double-tag-manager> 
 
    </div> 
 
</body> 
 

 
</html>

+0

我感覺自己就像不是更具體的白癡。我想要做的是將「所有食物」選項添加到第二選擇(用戶可能喜歡所有比薩餅,但不是所有的漢堡包)。應用您的解決方案(包括每個父類別的名爲'All Foods'的範圍項目)對於此更具體的描述並不理想,因爲API即時通訊工作不會像那樣返回數據。我會去看看你在早上發佈的那個庫,並給你的代碼另外一個樣子。 – Erik

0

尋找更進棧溢出後的最佳(也許只)的解決方案是鏈,將克隆過濾陣列和不印字另一種選擇另一濾光器。

新的過濾器:

app.filter('addAll', function() { 
    return function(input) { 
    // clone the array, or you'll end up with a new "None" option added to your "values" 
    // array on every digest cycle. 
    var newArray = input.slice(0); 
    newArray.unshift({name: "All Foods"}); 
    return newArray; 
    }; 
}); 

更新NG選項標籤:

ng-options="item.name for item in (secondary | filter: {parent_id: userPrimary.id} | addAll) 
      track by item.name" 

SO post

Updated Fiddle

相關問題