2015-10-08 2 views
1

Я пытаюсь сделать динамичную форму в угловых 1.4.7, в котором:Угловые динамические выбирает есть пункты, которые влияют друг на друга

  • Есть несколько отчетов (vm.reports = [];)
  • Каждый отчет может быть назначен ОДИНобъект via vm.reportOptions.
  • Каждый vm.reportOptions может быть выбран только ОДИН через несколько отчетов, которые фильтруются через exclude.
  • В каждом отчете поддерживается МНОГИЕdimensionОбъекты via vm.dimensionOptions.
  • Каждое измерение может быть выбрано только ОДИН за отчет, который фильтруется через excludeDimensions (последующие отчеты имеют доступ ко всем dimensionOptions и фильтруют сами).

Эти требования все работают (примерно) за исключением:

  • Если добавить два отчета, и добавьте точно такие же размеры (то есть: Report One>Размеры Один>Включить размерный фильтр и Report Two>Размеры Один>Включить размерный фильтр) для каждого из отчетов, изменяя выбор внутри Включить фильтр размеров изменяет его в обоих отчетах.

Я предполагаю, что это происходит из-за того, что я раздвигают реальные объекты измерения и отчета каждой 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

Смежные вопросы