我已经创建了一个自定义指令作为<select>
元素的替代品(我们可能有数百万条结果,所以我将其拆分为页面)。
其中一个用途是为动态创建的对象赋值,当将值赋值给该对象的第一个项时,它工作得很好,但是当我尝试分配第二个或更多时,它只会覆盖第一个ngModel
由于该项目是为了工作而保密,因此我将添加最低限度的代码,除非您需要查看更多代码(当然它们都将被编辑)。
感谢您的帮助
ks-select-modal
指令:app.controller('SelectModalCtrl', function($scope)
{
});
app.directive('ksSelectModal', function($parse)
{
var rtn =
{
restrict: 'E',
templateUrl: "/scripts/directives/ksSelectModal/ksSelectModalPrivate.html",
scope: {
mdNoFloat: '@',
ksPlaceholder: '@',
ksArray: '=',
ksDisplay: '=',
ngModel: '=',
ksTitle: '=',
ksNoMargin: '@',
ksInclude: '@',
ksInit: '=',
ksId: '@',
ksResults: '@',
ksChangePage: '&',
ksRequired: '@'
},
require: 'ngModel',
controller: function($scope)
{
if ($scope.selectModel === undefined)
{
$scope.selectModal = {
inScope: true
};
}
},
link: function($scope, element, attrs, ngModel)
{
var model = $parse(attrs.ngModel);
console.log(model);
$scope.$watch('ngModel', function(newValue, oldValue)
{
console.log(newValue);
});
if ($scope.ksRequired)
{
ngModel.$validators.ksRequired = function (modelValue, viewValue)
{
console.log('test');
if (viewValue)
{
ngModel.$setValidity('ksRequired', true);
}
else
{
ngModel.$setValidity('ksRequired', false);
}
console.log(ngModel.$valid);
return viewValue;
};
}
}
};
return rtn;
});
app.directive('ksSelectModalPrivate', function($parse, $q, $timeout, $compile, $http, $mdDialog, $document)
{
var rtn =
{
restrict: 'E',
templateUrl: "/scripts/directives/ksSelectModal/ksSelectModal.html",
scope: {
mdNoFloat: '=',
ngModel: '=',
ksResults: '=',
ksPlaceholder: '=',
ksArray: '=',
ksDisplay: '=',
ksTitle: '=',
ksNoMargin: '=',
ksInclude: '=',
ksId: '=',
ksChangePage: '=',
ksRequired: '='
},
require: 'ngModel',
link: function($scope, element, attrs, ngModel)
{
var model = $parse(attrs.ngModel);
$scope.$watch('filter', function(newValue, oldValue)
{
if ($scope.prevSearch)
{
$timeout.cancel($scope.prevSearch);
}
$scope.prevSearch = $timeout(function()
{
$scope.FirstPage();
}, 1000);
});
$scope.Open = function(ev)
{
$scope.$parent.selectModal.Open(ev);
};
$scope.OnSelect = function(value)
{
$scope.$parent.selectModal.OnSelect(value);
};
$scope.FirstPage = function()
{
angular.element('#' + $scope.ksId + ' .loading').css('display', 'block');
$scope.$parent.selectModal.page = 1;
$scope.ksChangePage({
page: $scope.$parent.selectModal.page,
results: $scope.ksResults,
filter: $scope.filter
}).then(function()
{
angular.element('#' + $scope.ksId + ' .loading').css('display', 'none');
});
}
$scope.NextPage = function()
{
angular.element('#' + $scope.ksId + ' .loading').css('display', 'block');
$scope.$parent.selectModal.page++;
$scope.ksChangePage({
page: $scope.$parent.selectModal.page,
results: $scope.ksResults,
filter: $scope.filter
}).then(function()
{
angular.element('#' + $scope.ksId + ' .loading').css('display', 'none');
});
}
$scope.PrevPage = function()
{
angular.element('#' + $scope.ksId + ' .loading').css('display', 'block');
$scope.$parent.selectModal.page--;
$scope.ksChangePage({
page: $scope.$parent.selectModal.page,
results: $scope.ksResults,
filter: $scope.filter
}).then(function()
{
angular.element('#' + $scope.ksId + ' .loading').css('display', 'none');
});
}
$scope.$parent.selectModal = {
isOpen: false,
element: element,
page: 1,
OnSelect: function(value)
{
$scope.$parent.selectModal.isOpen = false;
console.log($scope.ngModel);
ngModel.$viewModel = value;
model.assign($scope, value);
console.log(ngModel.$viewModel);
$mdDialog.hide();
$scope.$watch(ngModel.$viewModel, function(newValue, oldValue)
{
if (newValue == null)
{
angular.element($scope.$parent.selectModal.element).children('md-input-container').children('label').css({
display: 'block'
});
}
});
if ($scope.mdNoFloat !== undefined)
{
angular.element($scope.$parent.selectModal.element).children('md-input-container').children('label').css({
display: 'none'
});
}
else
{
angular.element($scope.$parent.selectModal.element).children('md-input-container').addClass('md-input-has-value');
angular.element($scope.$parent.selectModal.element).children('md-input-container').removeClass('md-input-focused');
}
},
Open: function(ev)
{
$scope.$parent.selectModal.isOpen = true;
if ($scope.mdNoFloat !== undefined)
{
}
else
{
angular.element($scope.$parent.selectModal.element).children('md-input-container').addClass('md-input-focused');
}
console.log($scope.ksId);
$mdDialog.show({
contentElement: '#' + $scope.ksId,
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true
}).finally(function()
{
$scope.$parent.selectModal.isOpen = false;
});
}
};
var elemClickHandler = function(e)
{
e.stopPropagation();
};
var docClickHandler = function()
{
if (!$scope.$parent.selectModal.isOpen)
{
angular.element($scope.$parent.selectModal.element).children('md-input-container').removeClass('md-input-focused');
}
};
element.on('click', elemClickHandler);
$document.on('click', docClickHandler);
}
};
return rtn;
});
ksSelectModal.html
<style>
ks-select-modal .md-button:hover:not([disabled])
{
background-color: transparent;
}
ks-select-modal .md-button:hover:not([disabled]) .md-list-item-inner
{
color:rgba(0, 0, 0, 0.87) !important;
}
ks-select-modal md-list-item
{
border-bottom:1px solid rgba(0,0,0,0.12);
}
ks-select-modal .md-input-focused md-list-item
{
border-bottom: 2px solid rgb(63,81,181);
}
</style>
<md-input-container ng-style="{ 'margin': (ksNoMargin ? '0px' : 'inherit') }">
<label style="bottom:77%; padding-left: 5px;">{{ ksPlaceholder }}</label>
<md-list>
<md-list-item md-no-ink ng-click="Open($event)">
<span style="margin-left: -15px;" ng-bind="ksDisplay"></span>
<md-icon class="md-secondary" md-svg-src="/v1/images/icons/ic_arrow_drop_down_black_24px.svg" style="margin-right: -20px;"></md-icon>
</md-list-item>
</md-list>
</md-input-container>
<div style="display: none" ng-init="FirstPage()">
<div class="md-dialog-container" id="{{ksId}}">
<md-dialog layout-padding>
<p>{{ ksTitle }}</p>
<div>
<md-button class="md-primary md-raised" ng-click="PrevPage()" ng-if="$parent.selectModal.page > 1">
<i class="mdi mdi-chevron-left"></i>
</md-button>
<md-button class="md-primary md-raised md-secondary" ng-click="NextPage()">
<i class="mdi mdi-chevron-right"></i>
</md-button>
<md-input-container>
<label>Filter</label>
<input type="text" ng-model="filter" />
</md-input-container>
<md-progress-circular style="position:absolute;top:30px;right:30px;" md-mode="indeterminate" class="md-secondary loading"></md-progress-circular>
</div>
<ng-include src="ksInclude"></ng-include>
</md-dialog>
</div>
</div>
ksSelectModalPrivate.html
<ks-select-modal-private md-no-float="mdNoFloat"
ng-model="ngModel"
ks-placeholder="ksPlaceholder"
ks-array="ksArray"
ks-display="ksDisplay"
ks-title="ksTitle"
ks-no-margin="ksNoMargin"
ks-id="ksId"
ks-required="ksRequired"
ks-change-page="ksChangePage"
ks-results="ksResults"
ks-include="ksInclude">
</ks-select-modal-private>
这是指令与ngRepeat一起使用的地方:
<md-list flex="100" flex-sm="100" flex-xs="100">
<md-subheader class="md-no-sticky">Properties</md-subheader>
<md-list-item ng-repeat="item in selectedProperties" id="property-list">
<p>{{ item.DisplayText}}</p>
<md-content class="md-secondary">
<table>
<tr>
<td align="right" style="width:100%;">
<ks-select-modal style="width:100%"
ks-id="selectDataType"
ks-title="'Select Data Type'"
ks-array="dataTypes"
ks-placeholder="Select Data Type"
ng-model="item.DataType"
ks-display="item.DataType._DataType"
ks-results="21"
ks-required="true"
ks-change-page="GetDataTypes(page, results, filter)"
ks-include="/v1/views/pages/site/modals/select-data-type.html">
</ks-select-modal>
<div ng-messages="item.DataType.$error">
<div ng-message="ksRequired">required</div>
</div>
</td>
<td align="right">
<md-button class="md-icon-button" aria-label="Remove" ng-click="RemoveProperty(item.Id)">
<md-icon md-svg-icon="images/icons/ic_delete_black_24px.svg"></md-icon>
</md-button>
</td>
</tr>
</table>
</md-content>
</md-list-item>
<md-divider></md-divider>
<ks-select-modal style="width:100%"
ks-title="'Select Property'"
ks-array="propertyConcepts"
ks-id="selectProperty"
md-no-float
ks-no-margin
ks-placeholder="Select Property"
ng-model="lastProperty"
ks-display="lastProperty.DisplayText"
ks-results="21"
ks-change-page="GetProperties(page, results, filter)"
ks-include="/v1/views/pages/site/modals/select-concept.html"></ks-select-modal>
</md-list>
select-data-type.html
<md-list>
<md-list-item ng-repeat="dataType in ksArray" style="float:left; width:30%;min-width:300px;">
{{ dataType._DataType }}
<md-button class="md-secondary" ng-click="OnSelect(dataType)">Select</md-button>
</md-list-item>
</md-list>
唯一需要的其他信息是$watch
范围变量上有lastProperty
,它将值添加到selectedProperties
数组中。
非常感谢任何帮助。
答案 0 :(得分:1)
我已经解决了这个问题。
传递到ksId
的ID对于ngRepeat
创建的所有元素都是相同的。通过更改ksId
值以将{{$index}}
添加到其末尾可以解决问题。