2017-08-29 73 views
1

我是Angular的新人。我做了一个“重复级联表”: 连接每一行。如果在第1行第1列(R1C1)中发生了某些变化,则该行中的其他两列将被级联。Angular ng-repeat with directive(in a cascaded repeat table)

我创建了两个“强盗”来展示我的问题。

  1. 通过自定义指令(为NG-重复) (http://plnkr.co/edit/J8k74C3AUIAxv6rEKcWL?p=preview
  2. 相同的,但没有指令(http://plnkr.co/edit/neOgWfuyuFnkawRGJB0c?p=preview

例2,当在R1C1 “功能” 是选择,并在R1C2中选择一个随机选项,然后用级联选项填充R1C3。

在同一个例子中,当一个行被添加(R2)并且在R2C1中选择“department”并且在R2C2中另一个随机选项R2C3被填充级联选项BUT ... R1C3也改变...

当我使用自定义指令时,这个问题就解决了。但是,每行的删除按钮不起作用($ index也是如此),并且json格式的表单数据也没有被填充。我怎样才能使这两个抢劫者完美匹配?我打破我的头在这个:(

PLUNKER码(例如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/[email protected]/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/[email protected]/dist/formly.js"></script> 
    <!-- This is the latest version of formly bootstrap templates --> 
    <script src="//npmcdn.com/[email protected]/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

在你的第二个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

+0

谢谢!我也试图upvote你的答案,但我是一个菜鸟(我收到一条消息,它被记录,但不公开可见)。 – lhartman

+0

您需要至少15个声望来提供答案。 –

0

好吧,我想你在呼唤剪接在指令里面,但是过滤器没有在指令中定义,你应该做的就是将函数也传递给指令,就像你已经通过了'过滤器'一样,'remove'函数可以在外部控制器上, s

scope: { 
    filter: "=", 
    removeFn: "&" 
} 

这样你就可以在指令中触发这个函数并通过滤波器去除。

你也可以通过所有过滤器的指令,然后让他们在你的范围,然后从功能指令删除您alreday有

编辑:第二个解决方案,可以只用2行代码来实现,但我不喜欢太多是这样的:

scope: { 
    filter: "=", 
    filters: "=" 
} 

和指令添加

<tr data-ng-repeat="item in filters" class="text-center" filter="item" filters="filters">