2015-10-08 79 views
1

我試圖使角1.4.7動態形式,其中:角動態選擇具有影響的項目彼此

  • 有多個報告(vm.reports = [];
  • 每個報告可以分配ONE報告對象通過vm.reportOptions
  • 每個vm.reportOptions才能選擇ONCE跨越多個報告,其經由exclude過濾。
  • 每個報告支持很多dimension對象通過vm.dimensionOptions
  • 每個維度只能選擇ONCE每個報告,這是通過excludeDimensions篩選(後續報告可以訪問所有dimensionOptions和過濾器自己)。

這些要求是所有工作(大致)有例外:

  • 如果我添加了兩份報告,並添加完全相同尺寸(即:報告一>Dimension One>啓用尺寸過濾器報告二>尺寸一>爲每個報告啓用尺寸過濾器),更改中的選擇啓用尺寸過濾器在兩個報告中都會更改它。

我認爲這是因爲我將實際尺寸對象推入每個報表dimensions: []數組中並且它們仍指向同一個對象。

- 編輯 -

我意識到angular.clone()就是要打破這個參考的好辦法,但<select>代碼我寫在對象模型自動管道。我很想給每個報告自己的控制者,並給每個報告自己的copy()的選項。

會這樣嗎?還是有更好的方式?我有一個工作JSBin here

相關代碼:

HTML:

<body ng-app="app"> 

    <div ng-controller="AlertsController as alerts"> 

    <pre>{{alerts.output(alerts.reports)}}</pre> 

    <div class="container"> 

    <div 
     ng-repeat="report in alerts.reports" 
     class="report" 
    > 
     <button 
     ng-if="$index !== 0" 
     ng-click="alerts.removeItem(alerts.reports,report)" 
     >Delete Report</button> 

     <label>Select Report</label> 
     <select 
     ng-model="alerts.reports[$index].report" 
     ng-init="report" 
     ng-options="reportSelect.niceName for reportSelect in alerts.reportOptions | exclude:'report':alerts.reports:report" 
     ></select> 

     <div 
     ng-repeat="dimension in report.dimensions" 
     class="condition" 
     > 
     <div class="select"> 
      <h1 ng-if="$index === 0">IF</h1> 
      <h1 ng-if="$index !== 0">AND</h1> 
      <select 
      ng-model="report.dimensions[$index]" 
      ng-change="alerts.checkThing(report.dimensions,dimension)" 
      ng-init="dimension" 
      ng-options="dimensionOption.niceName for dimensionOption in alerts.dimensionOptions | excludeDimensions:report.dimensions:dimension" 
      > 
      <option value="123">Select Option</option> 
      </select> 
      <button 
      class="delete" 
      ng-if="$index !== 0" 
      ng-click="alerts.removeItem(report.dimensions,dimension)" 
      >Delete</button> 
     </div> 


     <input type="checkbox" ng-model="dimension.filtered" id="filter-{{$index}}"> 
     <label class="filter-label" for="filter-{{$index}}">Enable Dimension Filter</label> 

     <div ng-if="dimension.filtered"> 
      <select 
      ng-model="dimension.operator" 
      ng-options="operator for operator in alerts.operatorOptions"> 
      </select> 
      <input 
      ng-model="dimension.filterValue" 
      placeholder="Text" 
      ></input> 
     </div> 

     </div> 

     <button 
     ng-click="alerts.addDimension(report)" 
     ng-if="report.dimensions.length < alerts.dimensionOptions.length" 
     >Add dimension</button> 
    </div> 

    <button 
     ng-if="alerts.reports.length < alerts.reportOptions.length" 
     ng-click="alerts.addReport()" 
    >Add report</button> 

    <!-- 
     <div ng-repeat="sel in alerts.select"> 
     <select ng-model="alerts.select[$index]" ng-init="sel" 
     ng-options="thing.name for thing in alerts.things | exclude:alerts.select:sel"></select> 
    </div> 
    --> 

    </div><!-- container --> 

    </div> 

</body> 

JS:

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

app.controller('AlertsController', function(){ 
    var vm = this; 

    vm.reportOptions = [ 
    {id: 1, niceName: 'Report One'}, 
    {id: 2, niceName: 'Report Two'}, 
    {id: 3, niceName: 'Report Three'}, 
    ]; 
    vm.dimensionOptions = [ 
    {id: 1, niceName: 'Dimension One'}, 
    {id: 2, niceName: 'Dimension Two'}, 
    {id: 3, niceName: 'Dimension Three'}, 
    ]; 
    vm.operatorOptions = [ 
    '>', 
    '>=', 
    '<', 
    '<=', 
    '=', 
    '!=' 
    ]; 

    ////// DEBUG STUFF ////// 
    vm.output = function(value) { 
    return JSON.stringify(value, undefined, 4); 
    } 
    //////////////////////// 


    vm.reports = []; 
    vm.addReport = function() { 
    vm.reports.push({report: {id: null}, dimensions: []}); 
    } 

    vm.removeItem = function(array,item) { 
    if(array && item) { 
     var index = array.indexOf(item); 
     if(index > -1) { 
     array.splice(index,1); 
     } 
    } 
    } 

    vm.addDimension = function(report) { 
    console.log('addDimension',report); 
    if(report) { 
     report.dimensions.push({}) 
    } 
    }; 

    // init 
    if(vm.reports.length === 0) { 
    vm.reports.push({report: {}, dimensions: [{}]}); 
//  vm.reports.push({report: vm.reportOptions[0], dimensions: [vm.dimensionOptions[0]]}); 
    } 

}); 

app.filter('excludeDimensions', [function() { 
    return function(input,select,selection) { 
//  console.log('ed',input,select,selection); 
    var newInput = []; 
    for(var i = 0; i < input.length; i++){ 
     var addToArray=true; 
     for(var j=0;j<select.length;j++){ 
      if(select[j].id===input[i].id){ 
       addToArray=false; 
      } 
     } 
     if(addToArray || input[i].id === selection.id){ 
     newInput.push(input[i]); 
     } 
    } 
    return newInput; 
    } 
}]); 

app.filter('exclude', [function() { 
    return function(input,type,select,selection){ 
    var newInput = []; 
    for(var i = 0; i < input.length; i++){ 
     var addToArray=true; 
     for(var j=0;j<select.length;j++){ 
      if(select[j][type].id===input[i].id){ 
       addToArray=false; 
      } 
     } 
     if(addToArray || input[i].id === selection[type].id){ 
     newInput.push(input[i]); 
     } 
    } 
    return newInput; 
    }; 
}]); 

回答

0

我結束了使用select as所以,它只是設置的對象,而不是指向原來的對象上的id。這解決了這個問題。

1

我如何圍繞推動相同的對象引用數組

使用angular.copy()

array.push(angular.copy(vm.formObject)); 
// clear object to use again in form 
vm.formObject={}; 
+0

是的,我最初是這樣做的,因爲所提供的值將通過「服務」管道。但是,如何在選擇更改時複製'formObject'?現在,從列表中選擇爲我做所有的魔術。 – tr3online

+0

我一直在試圖爲每個報告使用一個控制器,並讓它們只包含自己的上下文。這是一個好的解決方案嗎? – tr3online

+0

可以複製項目進行編輯,如果你不想直播模型更新,直到保存.....然後使用'angular.extend()'將更改合併到實時模型 – charlietfl