如何使用 ng-repeat 动态转发器字段保存值

How to save value with ng-repeat Dynamic repeater field

带有 AngularJS

的动态转发器字段

我是 AngularJS 的新手。我已经设法动态生成转发器字段,但我不知道如何保存它的值。

中继器值来自 PHP 中的数组。它会是这样的:

$repeater = [
    'name' => 'redirections',
    'title' => 'Redirection',
    'add_button_text' => 'New redirection',
    'save_button_text' => 'Save',
    'delete_button_text' => 'Remove redirection',
    'fields' => [
        [
            'name' => 'old_url',
            'type' => 'url',
            'label' => 'Old URL'
        ],
        [
            'name' => 'new_url',
            'type' => 'url',
            'label' => 'New URL'
        ]
    ]
];

然后我在 HTML 中呈现的信息是这样的:

<div class="field-container repeater">
    <div class="field-wrapper" ng-repeat="(key, item) in repeaterItems">
        <div class="title" ng-click="toggleRepeater($event)">
            <span>{{ field.title }}</span>
            <span ng-repeat="input in field.fields" class="field-block">
            </span>
        </div>
        <div class="inside">
            <div class="inputs" ng-repeat="(index, input) in field.fields">
                <label>
                    {{ input.label }}
                    <input type="{{ input.type }}" name="{{ input.name }}"
                           value="{{ input.value }}" ng-model="input.value"
                           ng-change="update_repeater_item()">
                </label>
            </div>
            <span class="delete"><span ng-click="remove_repeater_item($event)">
              {{ field.delete_button_text }}
            </span></span>
        </div>
        <input id="{{ item.id }}" class="{{ item.id }} repeater-item-value"
               type="hidden" name="{{ field.name }}[{{ item.id }}][]" value="">
    </div>

    <button class="repeater-button add-button" ng-click="add_repeater_item($event)">
      {{ field.add_button_text }}
    </button>
    <button class="repeater-button save-button" ng-click="save_repeater($event)">
      {{ field.save_button_text }}
    </button>
</div>

最后,我对 Angular 的看法是:

scope.repeaterItems = [];
scope.toggleRepeater = function($event) {
    const clicked = angular.element($event.currentTarget);
    const inside = angular.element($event.currentTarget.nextElementSibling);
    if (clicked.hasClass('open')) {
        clicked.removeClass('open');
        inside.removeClass('show'); // .inside
    }
    else {
        clicked.addClass('open');
        inside.addClass('show'); // .inside
    }
};

scope.add_repeater_item = function() {
    scope.repeaterItems.push({
        'id': Date.now().toString(36) + Math.random().toString(36).substr(2),
        'value': {}
    });
};

scope.remove_repeater_item = function($event) {
    const clicked = $event.currentTarget;
    const container = clicked.closest('.field-wrapper'); // .field-wrapper
    const inputs = container.getElementsByTagName('input');
    let deletedItemId = '';
    for (let input of inputs) {
        if (input.type === 'hidden') {
            deletedItemId = input.id;
        }
    }
    scope.repeaterItems = $filter('filter')(scope.repeaterItems, {id: '!' + deletedItemId}, true);
};
scope.update_repeater_item = function(value) {
    console.log(value);
};

scope.save_repeater = function($event) {
    console.log($event);    
};

我从这段代码中得到的视觉效果是这样的(以防有帮助): Repeater rendering

感谢您对当前代码的任何帮助或改进。谢谢。

将输入绑定到 ng-repeat 项值对象的属性:

<div ng-repeat="item in repeaterItems" ng-init="itemIndex = $index">
    <div ng-repeat="input in field.fields">
        <label>
            {{ input.label }}
            <input type="{{ input.type }}" name="{{ input.name + itemIndex}}"
                   ng-model="item.value[input.name]"
                   ng-change="update_repeater_item(item, itemIndex, input.name)">
        </label>
    </div>
    <span ng-click="remove_repeater_item(itemIndex)">
      {{ field.delete_button_text }}
    </span>
</div>

<button class="add-button" ng-click="add_repeater_item()">
  {{ field.add_button_text }}
</button>
<button class="save-button" ng-click="save_repeater(repeaterItems)">
  {{ field.save_button_text }}
</button>

这简化了代码:

$scope.repeaterItems = [];

$scope.add_repeater_item = function() {
    $scope.repeaterItems.push({
        'id': Date.now().toString(36) + Math.random().toString(36).substr(2),
        'value': {}
    });
};

$scope.remove_repeater_item = function(index) {
    console.log("removing", $scope.repeaterItems[index].id);
    $scope.repeaterItems.splice(index,1); 
};

scope.update_repeater_item = function(item, index, name) {
    console.log(item.id, item.value);
    console.log($scope.repeaterItems[index]);
    console.log(name + ' changed to ' + item.value[name]);
};

$scope.save_repeater = function(items) {
    console.log(items);
    $http.post(url, items);    
};