Я пытаюсь создать угловую директиву, которая является оболочкой поверх директивы ui-select. Моя цель - предоставить директиве список с элементами и моделью, которая будет синхронизироваться с определенным свойством выбранного элемента (ов). Моя директива имеет 5 атрибутов:Как создать угловую директиву ui-select, которая связывает свойство выбранного элемента с моделью
ng-model - to specify the model, items - to specify the list of items, display-prop - the name of the property which will be used inside ui-select for display purpose, value-prop - the name of the property which will be used for model assignment, multiple [optional] - if multiple selection is allowed
В директиве рамки ребенка у меня есть объект, который синхронизируется с Ui-выберите нг-моделью и при его изменении я обновляя основной объем.
Мне удается сделать все, что работает для одного выбранного элемента, и для нескольких элементов, когда вы начинаете с пустого выбора. Однако у меня все еще есть проблема с отображением начальных выбранных элементов, когда выбран множественный выбор. Я думаю, что проблема где-то с областями и методами $ watch между моей директивой и директивой ui-select. Похоже, что обновления в моей области директивы не влияют на u-select ng-model в случае массива.
Я создал Plunker с простым приложением, содержащим директиву и тестовый пример, где вы можете видеть, что один отбор работает правильно, но когда у меня есть массив, список не инициализируется.
angular.module('dgUi', ['ui.select', 'ngSanitize'])
.config(['uiSelectConfig', function(uiSelectConfig){
uiSelectConfig.theme = 'select2';
}])
.controller('UiSelectWrapperConttoller', ['$scope', function($scope){
$scope.userAddresses = [
{
address: 'Address 1',
description: 'Home address'
},
{
address: 'Address 2',
description: 'Office address'
},
{
address: 'Address 3',
description: 'Test address 3'
},
{
address: 'Address 4',
description: 'Test address 4'
}
];
$scope.currentUser = {
name: 'User 1',
address: 'Address 1'
};
$scope.currentUser = {
name: 'User 1',
address: 'Address 2',
availableAddresses:['Address 3']
};
}])
.directive('dgSelect', ['$parse', function ($parse) {
return {
restrict: 'AE',
require: ['ngModel'],
scope: true,
templateUrl: function(tElement, tAttrs) {
return '/global/dg-ui/dg-select' + ((angular.isDefined(tAttrs.multiple) ? '-multi' : '') + '.tpl.html');
},
compile: function (tElement, tAttrs) {
var displayPropSufix = tAttrs.displayProp ? '.' + tAttrs.displayProp : '';
var isMultiple = angular.isDefined(tAttrs.multiple) ;
//match element config
if (tAttrs.placeholder) {
$('ui-select-match, *[ui-select-match]', tElement).attr('placeholder', tAttrs.placeholder);
}
if(isMultiple){
$('ui-select-match, *[ui-select-match]', tElement).html('{{$item' + displayPropSufix + '}}');
}else{
$('ui-select-match, *[ui-select-match]', tElement).html('{{$select.selected' + displayPropSufix + '}}');
}
//choices element config
$('ui-select-choices, *[ui-select-choices]', tElement).attr('repeat', 'listItem in ' + tAttrs.items + ' | filter:$select.search')
$('ui-select-choices, *[ui-select-choices]', tElement).html('<div ng-bind-html="listItem' + displayPropSufix + ' | highlight: $select.search"></div>');
return function link(scope, element, attrs, ctrls) {
scope.ngModel = ctrls[0];
scope.isMultiple = angular.isDefined(attrs.multiple)
scope.itemsGetter = $parse(attrs.items);
if(angular.isDefined(attrs.valueProp) && attrs.valueProp !== ''){
scope.valuePropGetter = $parse(attrs.valueProp);
}
scope.getValueMapper = function(itemObject){
return scope.valuePropGetter ? scope.valuePropGetter(itemObject) : itemObject;
}
scope.updateValueFromModel = function(modelValue){
if(scope.isMultiple){
var selectionArray = [];
angular.forEach(modelValue, function(modelItem, key){
var modelItemValue = scope.getValueMapper(modelItem);
selectionArray.push(modelItemValue);
});
scope.selectionModel = selectionArray;
}else{
var items = scope.itemsGetter(scope);
angular.forEach(items, function(item, key){
var itemValue = scope.getValueMapper(item);
if(itemValue == modelValue){
scope.selectionModel = item;
return false;
}
});
}
}
if(scope.isMultiple){
scope.$watchCollection(attrs.ngModel, function(modelValue, oldValue) {
scope.updateValueFromModel(modelValue);
});
}else{
scope.$watch(attrs.ngModel, function(modelValue){
scope.updateValueFromModel(modelValue);
});
}
//watch the items in case of async loading
//scope.$watch(attrs.items, function(){
// scope.updateValueFromModel(scope.ngModel.$modelValue);
//});
scope.onItemSelect = function(item, model){
var movelValue = scope.getValueMapper(item);
if(scope.isMultiple){
scope.ngModel.$viewValue.push(movelValue);
}else{
scope.ngModel.$setViewValue(movelValue);
}
}
scope.onItemRemove = function(item, model){
var removedModelValue = scope.getValueMapper(item);
if(scope.isMultiple){
var removeIndex = null;
angular.forEach(scope.ngModel.$viewValue, function(itemValue, index){
if(itemValue == removedModelValue){
removeIndex = index;
return false;
}
});
if(removeIndex){
scope.ngModel.$viewValue.splice(removeIndex, 1);
}
}else{
scope.ngModel.$setViewValue(movelValue);
}
}
}
}
};
}])
.run(['$templateCache', function ($templateCache) {
$templateCache.put('/global/dg-ui/dg-select.tpl.html',
'<ui-select class="ui-select" ng-model="selectionModel" on-select="onItemSelect($item, $model)" on-remove="onItemRemove($item, $model)" ng-disabled="disabled"><ui-select-match></ui-select-match><ui-select-choices></div></ui-select-choices></ui-select>');
$templateCache.put('/global/dg-ui/dg-select-multi.tpl.html', '<ui-select class="ui-select" multiple ng-model="selectionModel" on-select="onItemSelect($item, $model)" on-remove="onItemRemove($item, $model)" ng-disabled="disabled"><ui-select-match></ui-select-match><ui-select-choices></ui-select-choices></ui-select>');
}]);
Возможно, я делаю что-то неправильно здесь. Я был бы очень признателен за любую помощь :), спасибо!
Большое спасибо, вот и думаю, что я ищу :). –