Не отображается коллекция в template angularjs

208
23 апреля 2018, 23:28

Здравствуйте, недавно начала изучать angularjs и столкнулась с трудностью. Создала отдельный компонент для формы некой сущности (поля: объект, субъект, действие, параметры). При нажатии на кнопку Сохранить, объект этой сущности должен сохраняться в коллекции и выводиться в списке ниже. Но список в template обновляться не хочет и не могу понять почему. Прикладываю код контроллера и шаблона.

Контроллер:

'use strict';
angular.
  module('usecaseForm').
  component('usecaseForm', {
    templateUrl: 'usecase-form/usecase-form.template.html',
    controller: function UsecaseFormController() {
        var ctrl = this;
        ctrl.usecases = new Set();
        ctrl.usecase = {
            object: '',
            subject: '',
            action: '',
            parameters: []
        }
        ctrl.addUsecase = function() {
            ctrl.usecases.add({
                object: ctrl.usecase.object,
                subject: ctrl.usecase.subject,
                action: ctrl.usecase.action,
                parameters: ctrl.usecase.parameters
            })
            ctrl.usecase.object = '';
            ctrl.usecase.subject = '';
            ctrl.usecase.action = '';
            ctrl.usecase.parameters = '';
            console.log(ctrl.usecases);
        }
        ctrl.addParam = function() {
            ctrl.usecase.parameters.push(
                ctrl.usecase.parameter
            );
        }
    }
})

Шаблон:

<div class="lg-col-6">
    <form novalidate ng-submit="$ctrl.addUsecase()">
        <label>Object: <input type="text" ng-model="$ctrl.usecase.object" /></label><br />
        <label>Subject: <input type="text" ng-model="$ctrl.usecase.subject" /></label><br />
        <label>Action: <input type="text" ng-model="$ctrl.usecase.action" /></label><br />
        <label>Parameter: 
        <input type="text" ng-model="$ctrl.usecase.parameter" /></label>
        <input type="button" value="Add param" ng-click="$ctrl.addParam()"/><br />
        <select size="5" style="width: 30%">
            <option ng-repeat="param in $ctrl.usecase.parameters track by $index">
                {{param}}
            </option>   
        </select><br />
        </label>
        <input type="submit" value="Save" />
    </form>
    <ul>
        <li ng-repeat="usecase in $ctrl.usecases track by $index">
            {{usecase}}
        </li>
    </ul>
</div>
Answer 1

Дело в том, что angularjs не умеет работать с Set.

У вас есть три варианта:

  1. Не использовать Set, использовать простой массив. На мой взгляд - самый лучший вариант.
  2. Не использовать Set при ng-repeat. Преобразовывать Set в массив. Это можно сделать разными путями, используя пайп, в шаблоне преобразовать или в контроллере.
  3. Создать собственную директиву на основе ng-repeat, которая будет уметь использовать Set.

Пример второго варианта:

angular 
  .module('testApp', []) 
  .controller('UsecaseForm', function UsecaseFormController() { 
    var ctrl = this; 
    ctrl.usecases = new Set(); 
    ctrl.usecasesArr = new Set(); 
 
    ctrl.usecase = { 
      object: '', 
      subject: '', 
      action: '', 
      parameters: [] 
    } 
 
    ctrl.addUsecase = function() { 
      ctrl.usecases.add({ 
        object: ctrl.usecase.object, 
        subject: ctrl.usecase.subject, 
        action: ctrl.usecase.action, 
        parameters: ctrl.usecase.parameters 
      }) 
      ctrl.usecasesArr = Array.from(ctrl.usecases); 
      ctrl.usecase.object = ''; 
      ctrl.usecase.subject = ''; 
      ctrl.usecase.action = ''; 
      ctrl.usecase.parameters = []; 
 
    } 
 
    ctrl.addParam = function() { 
      ctrl.usecase.parameters.push( 
        ctrl.usecase.parameter 
      ); 
    } 
  }) 
  .filter('set2Array', function() { 
    return function(s) { 
      return Array.from(s); 
    } 
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> 
<div ng-app="testApp" ng-controller="UsecaseForm as ctrl" class="lg-col-6"> 
  <form novalidate ng-submit="ctrl.addUsecase()"> 
    <label>Object: <input type="text" ng-model="ctrl.usecase.object" /></label><br /> 
    <label>Subject: <input type="text" ng-model="ctrl.usecase.subject" /></label><br /> 
    <label>Action: <input type="text" ng-model="ctrl.usecase.action" /></label><br /> 
    <label>Parameter:  
        <input type="text" ng-model="ctrl.usecase.parameter" /></label> 
    <input type="button" value="Add param" ng-click="ctrl.addParam()" /><br /> 
    <select size="5" style="width: 30%"> 
      <option ng-repeat="param in ctrl.usecase.parameters track by $index"> 
        {{param}} 
      </option> 
    </select><br /> 
    <label></label> 
    <input type="submit" value="Save" /> 
  </form> 
 
  Переводим прямо в шаблоне(самый плохой вариант, не рекомендую) 
  <ul> 
    <li ng-repeat="usecase in [].constructor.from(ctrl.usecases)"> 
      {{usecase}} 
    </li> 
  </ul> 
 
 
  Используем массив для вывода 
  <ul> 
    <li ng-repeat="usecase in ctrl.usecasesArr"> 
      {{usecase}} 
    </li> 
  </ul> 
 
 
  Используем filter для вывода 
  <ul> 
    <li ng-repeat="usecase in ctrl.usecases|set2Array"> 
      {{usecase}} 
    </li> 
  </ul> 
 
</div>

READ ALSO
Как объединить этот код в один? (HTML+JS)

Как объединить этот код в один? (HTML+JS)

Имеется три JS файла которые на 95% одинаковы и три html файла в котором все это вызываетсяХочу все сделать покомпактнее и управиться в один html и один...

226
Удаление лишних функций js

Удаление лишних функций js

Здравствуйте, появилась проблемаЕсть огромный js фреймворк с кучей функций, есть ли возможность с помощью например gulp вырезать только функции...

182
Блок с img со свойствами как у background

Блок с img со свойствами как у background

Как сверстать блок у которого картинка будет заполнять всю его ширину или высоту также как background Стоит задача — именно картинкой тегом imgВот...

226