我是Angular的新手。我做了一个"重复级联表": 每行都是连接的。如果在第1行第1列(R1C1)中发生了某些变化,则该行中的其他2列将进行级联。
我创造了两个"掠夺者"证明我的问题。
在示例2 中,当处于R1C1"功能"选择,并在R1C2中选择一个随机选项,然后使用级联选项填充R1C3。
在同一个例子中,当添加一行(R2)并且在R2C1"部门"在R2C2中选择了另一个随机选项,R2C3填充了级联选项但是...... R1C3也改变了......
当我使用自定义指令时,这个问题就解决了。但是,每行的删除按钮不起作用($ index ...也是如此),并且还没有填充json格式的表单数据。我怎样才能在这两个掠夺者之间做出完美匹配?我对此表示不满:(
PLUNKER CODE(例2):
JS:
'use strict';
/* global $ */
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $timeout, filterService) {
$scope.filters = filterService.getFilters();
$scope.addNewForm = function (){
$scope.filters.push({});
};
$scope.attribute = filterService.getAttribute();
$scope.comparison = function(index, field) {
$scope.comparisonType = filterService.getComparison($scope.attribute[field]);
};
$scope.value = function(index, parent, field) {
$scope.vType = filterService.getValueType($scope.attribute[parent], $scope.comparisonType[field]);
}
})
app.service('filterService', function() {
var attribute = [
{name: 'Building year', type: 'integer', id: 1},
{name: 'Square meters', type: 'integer', id: 2},
{name: 'Function', type: 'select', id: 3},
{name: 'Department', type: 'multiselect', id: 4},
{name: 'Date of possesion', type: 'date', id: 5},
];
this.getFilters = function() {
return [];
}
this.getAttribute = function() {
return attribute;
}
this.getComparison = function(attribute) {
console.log(attribute.name)
var comparisonType = [];
if (attribute.type == 'select' || attribute.type == 'multiselect') {
comparisonType = [
{name: 'is', id: 1},
{name: 'is not', id: 2},
{name: 'one of', id: 3},
{name: 'not one of', id: 4},
]
} else if (attribute.type == 'integer' || attribute.type == 'date') {
comparisonType = [
{name: 'is', id: 1},
{name: 'is not', id: 2},
{name: 'greater then', id: 3},
{name: 'smaller then', id: 4},
]
}
return comparisonType;
}
this.getValueType = function(attribute, comparison) {
console.log(attribute.name)
console.log(comparison.name)
var vType = [];
var vTypes = [
{name: 'Department 1', id: 1, fk: 4},
{name: 'Department 2', id: 2, fk: 4},
{name: 'Department 3', id: 3, fk: 4},
{name: 'Department 4', id: 4, fk: 4},
{name: 'Department 5', id: 5, fk: 4},
{name: 'Function 1', id: 6, fk: 3},
{name: 'Function 2', id: 7, fk: 3},
{name: 'Function 3', id: 8, fk: 3},
{name: 'Function 4', id: 9, fk: 3},
{name: 'Function 5', id: 10, fk: 3},
]
var tmp = [];
angular.forEach(vTypes, function(value, key) {
if (value.fk === attribute.id)
tmp.push(value);
});
if (attribute.type == 'select') {
vType = [
{name: 'Department 1', id: 1, fk: 4},
{name: 'Department 2', id: 2, fk: 4},
{name: 'Department 3', id: 3, fk: 4},
{name: 'Department 4', id: 4, fk: 4},
{name: 'Department 5', id: 5, fk: 4},
{name: 'Function 1', id: 6, fk: 3},
{name: 'Function 2', id: 7, fk: 3},
{name: 'Function 3', id: 8, fk: 3},
{name: 'Function 4', id: 9, fk: 3},
{name: 'Function 5', id: 10, fk: 3},
];
}
//return vType;
return tmp;
}
});
HTML:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<!-- Twitter bootstrap -->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<!-- apiCheck is used by formly to validate its api -->
<script src="//npmcdn.com/api-check@latest/dist/api-check.js"></script>
<!-- This is the latest version of angular (at the time this template was created) -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<!-- This is the latest version of formly core. -->
<script src="//npmcdn.com/angular-formly@latest/dist/formly.js"></script>
<!-- This is the latest version of formly bootstrap templates -->
<script src="//npmcdn.com/angular-formly-templates-bootstrap@latest/dist/angular-formly-templates-bootstrap.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://rawgithub.com/eligrey/FileSaver.js/master/FileSaver.js" type="text/javascript"></script>
<script src="script.js"></script>
</head>
<body ng-controller="myCtrl">
<table class="table table-bordered" cellspacing="0" width="100%">
<th>Attribute</th>
<th>Compare</th>
<th>Value</th>
<th></th>
<tbody>
<tr data-ng-repeat="item in filters" class="text-center">
<td>
<select class="form-control"
ng-options='k as v.name for (k,v) in attribute'
ng-change='comparison($index, item.check1)'
ng-model='item.check1'>
<option value='' disabled>Select...</option>
</select>
</td>
<td>
<select ng-if="item.check1" class="form-control"
ng-model='item.check2'
ng-options='a as b.name for (a,b) in comparisonType'
ng-change='value($index, item.check1, item.check2)'>
<option value='' disabled>Select...</option>
</select>
</td>
<td>
<!--DATE-->
<input class="form-control" ng-if="item.check1==='4' && item.check2"
type="date" ng-model='item.check3'>
</input>
<!--INTEGER-->
<input ng-if="item.check1==='0' && item.check2"
class="form-control" ng-model='item.check3' type="number"
</input>
<!--SELECT-->
<select ng-if="item.check1==='2' && item.check2"
class="form-control" ng-model='item.check3'
ng-options='c as d.name for (c,d) in vType'>
<option value='' disabled>Select...</option>
</select>
<!--MULTIPLE-->
<select multiple ng-if="item.check1==='3'"
class="form-control" ng-model='item.check3'
ng-options='c as d.name for (c,d) in vType'>
</select>
</td>
<td>
<button data-index="$index" type="button"
class="btn btn-sm btn-danger"
ng-click="filters.splice($index, 1)" >
Remove
</button>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-default" id="addMore" aria-hidden="true"
ng-click="addNewForm()">Add</button>
<pre>{{filters | json}}</pre>
</body>
</html>
答案 0 :(得分:1)
在第二个plunker中,您正在分配来自$scope.vTypes
的第二个选择/多重选择值。这是控制器中的全局变量,因此当您选择department
进行修改后,function
部分也会收到新值。
您需要的是每个过滤器vTypes
。
所以,在你的js中你可以这样做:
$scope.value = function(index, parent, field) {
$scope.filters[index].vType = filterService.getValueType($scope.attribute[parent], $scope.comparisonType[field]);
}
在你的HTML中:
<td>
<!--SELECT-->
<select ng-if="item.check1==='2' && item.check2"
class="form-control" ng-model='item.check3'
ng-options='c as d.name for (c,d) in item.vType'>
<option value='' disabled>Select...</option>
</select>
<!--MULTIPLE-->
<select multiple ng-if="item.check1==='3'"
class="form-control" ng-model='item.check3'
ng-options='c as d.name for (c,d) in item.vType'>
</select>
</td>
这是一个带有示例的plunkr: http://plnkr.co/edit/nL23ScGLBrqFuHp48ZsL?p=preview
答案 1 :(得分:0)
好吧,我认为你在指令中调用splice,但过滤器没有在指令中定义。你应该做的是将函数传递给指令。就像你已通过'过滤器'。这个'remove'函数可以在外部控制器上并作为
传递scope: {
filter: "=",
removeFn: "&"
}
这样你可以在指令中触发这个函数并传递要删除的过滤器。
您也可以将所有过滤器传递给指令,然后将它们放在您的作用域中,然后使用您已经拥有的函数将它们从指令中删除
编辑:第二个解决方案,只需2行代码即可实现,但我不太喜欢它:scope: {
filter: "=",
filters: "="
}
并在指令中添加
<tr data-ng-repeat="item in filters" class="text-center" filter="item" filters="filters">