редактируется с помощью ngrepeat: автоматическое редактирование последнего добавленного элемента

Мне нужно добавить новые элементы в коллекцию, которая отображается с помощью ngrepeat, и с помощью xeditable сделать ее автоматически редактируемой.

Кстати, я использую метод «ручной триггер» для xeditable.

Вот это HTML

<h4>Angular-xeditable demo</h4>
<div ng-app="app" ng-controller="Ctrl" style="margin: 50px">
<div class="btn btn-default" ng-click="addNew()">+</div>
<ul>
  <li ng-repeat="item in array | orderBy:'-value'">
    <a href="#" e-form="itemForm" editable-text="item.field">{{ item.field }}</a>
    <i ng-show="!itemForm.$visible" ng-click="itemForm.$show()">edit</i>
  </li>
</ul>
</div>

а вот контроллер:

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

app.run(function(editableOptions) {
  editableOptions.theme = 'bs3';
});

app.controller('Ctrl', function($scope, $filter) {

  $scope.array = [
    {value: 1, field: 'status1'},
    {value: 2, field: 'status2'},
    {value: 3, field: 'status3'},
    {value: 4, field: 'status4'}
  ]; 

  $scope.addNew = function(){
    $scope.array.push({value:$scope.array.length+1, field: 'enter text here'});
    //MAKE IT EDITABLE????????
  }
});

Взгляните на проблему в этой скрипке: http://jsfiddle.net/dpamio/hD5Kh/1/


person Diego Pamio    schedule 16.11.2013    source источник
comment
пожалуйста объясните проблему   -  person charlietfl    schedule 17.11.2013
comment
когда написано //СДЕЛАТЬ ЭТО РЕДАКТИРУЕМЫМ?? Я имел в виду, перевести его в режим редактирования сразу после добавления элемента.   -  person Diego Pamio    schedule 18.11.2013
comment
ОК .. теперь понятно ... почему бы пользователю сначала не создать новый, а затем нажать на массив данных? скорее всего проще. Измените кнопку «Добавить», чтобы отобразить ввод и кнопку «Сохранить» ... при сохранении скройте ввод и вставьте эту модель в $scope.array   -  person charlietfl    schedule 18.11.2013
comment
да, это может сработать. Разве что я хотел подчеркнуть двустороннюю привязку по макс. Если я могу это сделать, мне не нужна дополнительная форма (это мое текущее решение).   -  person Diego Pamio    schedule 18.11.2013
comment
Я думаю, вам придется изменить редактируемую директиву, чтобы она открывалась в режиме редактирования.   -  person charlietfl    schedule 18.11.2013
comment
См. обсуждение в этой проблеме. Возможное решение здесь (требуется использование отдельного form): jsfiddle.net/NfPcH/215   -  person Sergey K    schedule 10.06.2014


Ответы (2)


Вот обновленная работающая скрипта. Из-за того, как была написана директива и как работает ng-repeat, потребовалось чрезвычайно хакерское решение...

app.controller('Ctrl', function($scope, $filter, $timeout) {

  $scope.itemForms = {};

  $scope.addNew = function(){
    $scope.array.push({value:$scope.array.length+1, field: 'enter text here'});

     // Use timeout to force evaluation after the element has rendered
     // ensuring that our assignment expression has run
     $timeout(function() {
         $scope.itemForms[0].$show(); // last index since we sort descending, so the 0 index is always the newest
     })
  }

Справочная информация о том, как работает ng-repeat: ng-repeat создаст новую дочернюю область для каждого повторяющегося элемента. Директива назначает переменную в этой области, используя строку, переданную в e-form для ее имени (в данном случае itemForm). Если бы он был умнее, он позволял бы вычислять выражение для присваивания. (Тогда мы могли бы назначить его родительской области и получить к нему доступ в контроллере, но это другое дело).

Поскольку у нас нет никакого способа получить доступ к этой дочерней области вне директивы, мы делаем что-то очень плохое. Мы используем выражение усов в диапазоне display none, чтобы присвоить переменную itemForm родительской области, чтобы мы могли использовать ее позже. Затем внутри нашего контроллера мы используем значение поиска для вызова ожидаемого метода itemForm.$show().

Абстрагируя эту гадость в директиву angular, мы могли бы написать следующее:

.directive('assignFromChild', function($parse) {
    return {
        restrict: 'A',
        link: function(scope, el, attrs) {
            scope.$watch(function() { return $parse(attrs.assignFromChild)(scope); }, function(val) {
                $parse('$parent.' + attrs.toParent).assign(scope, val);
            })
        }
    }; 
});

Разрешаем нашему HTML вернуться к:

<ul>   
  <li ng-repeat="item in array | orderBy:'-value'" assign-from-child="itemForm" to-parent="itemForms[{{$index}}]">
    <a href="#" e-form="itemForm" editable-text="item.field">{{ item.field }}</a>
    <i ng-show="!itemForm.$visible" ng-click="itemForm.$show()">edit</i>
  </li>
</ul>

Вот пример моего окончательного решения

person Ryan    schedule 28.02.2015

Я нашел очень простое решение с использованием ng-init="itemForm.$show()", которое активирует редактируемую форму при вставке нового элемента.

Вот обновленный jsFiddle, отвечающий на вопрос: http://jsfiddle.net/hD5Kh/15/

person cnlevy    schedule 12.04.2016