Edit In Place Content Editing

前端 未结 4 1745
暗喜
暗喜 2020-12-04 06:02

When using ng-repeat what is the best way to be able to edit content?

In my ideal situation the added birthday would be a hyperlink, wh

相关标签:
4条回答
  • 2020-12-04 06:24

    You should put the form inside each node and use ng-show and ng-hide to enable and disable editing, respectively. Something like this:

    <li>
      <span ng-hide="editing" ng-click="editing = true">{{bday.name}} | {{bday.date}}</span>
      <form ng-show="editing" ng-submit="editing = false">
        <label>Name:</label>
        <input type="text" ng-model="bday.name" placeholder="Name" ng-required/>
        <label>Date:</label>
        <input type="date" ng-model="bday.date" placeholder="Date" ng-required/>
        <br/>
        <button class="btn" type="submit">Save</button>
       </form>
     </li>
    

    The key points here are:

    • I've changed controls ng-model to the local scope
    • Added ng-show to form so we can show it while editing
    • Added a span with a ng-hide to hide the content while editing
    • Added a ng-click, that could be in any other element, that toggles editing to true
    • Changed ng-submit to toggle editing to false

    Here is your updated Plunker.

    0 讨论(0)
  • 2020-12-04 06:26

    I was looking for a inline editing solution and I found a plunker that seemed promising, but it didn't work for me out of the box. After some tinkering with the code I got it working. Kudos to the person who made the initial effort to code this piece.

    The example is available here http://plnkr.co/edit/EsW7mV?p=preview

    Here goes the code:

    app.controller('MainCtrl', function($scope) {
    
      $scope.updateTodo = function(indx) {
        console.log(indx);
      };
    
      $scope.cancelEdit = function(value) {
        console.log('Canceled editing', value);
      };
    
      $scope.todos = [
        {id:123, title: 'Lord of the things'},
        {id:321, title: 'Hoovering heights'},
        {id:231, title: 'Watership brown'}
      ];
    });
    
    // On esc event
    app.directive('onEsc', function() {
      return function(scope, elm, attr) {
        elm.bind('keydown', function(e) {
          if (e.keyCode === 27) {
            scope.$apply(attr.onEsc);
          }
        });
      };
    });
    
    // On enter event
    app.directive('onEnter', function() {
      return function(scope, elm, attr) {
        elm.bind('keypress', function(e) {
          if (e.keyCode === 13) {
            scope.$apply(attr.onEnter);
          }
        });
      };
    });
    
    // Inline edit directive
    app.directive('inlineEdit', function($timeout) {
      return {
        scope: {
          model: '=inlineEdit',
          handleSave: '&onSave',
          handleCancel: '&onCancel'
        },
        link: function(scope, elm, attr) {
          var previousValue;
    
          scope.edit = function() {
            scope.editMode = true;
            previousValue = scope.model;
    
            $timeout(function() {
              elm.find('input')[0].focus();
            }, 0, false);
          };
          scope.save = function() {
            scope.editMode = false;
            scope.handleSave({value: scope.model});
          };
          scope.cancel = function() {
            scope.editMode = false;
            scope.model = previousValue;
            scope.handleCancel({value: scope.model});
          };
        },
        templateUrl: 'inline-edit.html'
      };
    });
    

    Directive template:

    <div>
      <input type="text" on-enter="save()" on-esc="cancel()" ng-model="model" ng-show="editMode">
      <button ng-click="cancel()" ng-show="editMode">cancel</button>
      <button ng-click="save()" ng-show="editMode">save</button>
      <span ng-mouseenter="showEdit = true" ng-mouseleave="showEdit = false">
        <span ng-hide="editMode" ng-click="edit()">{{model}}</span>
        <a ng-show="showEdit" ng-click="edit()">edit</a>
      </span>
    </div>
    

    To use it just add water:

    <div ng-repeat="todo in todos" 
         inline-edit="todo.title" 
         on-save="updateTodo($index)" 
         on-cancel="cancelEdit(todo.title)"></div>
    

    UPDATE:

    Another option is to use the readymade Xeditable for AngularJS:

    http://vitalets.github.io/angular-xeditable/

    0 讨论(0)
  • 2020-12-04 06:33

    Since this is a common piece of functionality it's a good idea to write a directive for this. In fact, someone already did that and open sourced it. I used editablespan library in one of my projects and it worked perfectly, highly recommended.

    0 讨论(0)
  • 2020-12-04 06:35

    I've modified your plunker to get it working via angular-xeditable:

    http://plnkr.co/edit/xUDrOS?p=preview

    It is common solution for inline editing - you creale hyperlinks with editable-text directive that toggles into <input type="text"> tag:

    <a href="#" editable-text="bday.name" ng-click="myform.$show()" e-placeholder="Name">
        {{bday.name || 'empty'}}
    </a>
    

    For date I used editable-date directive that toggles into html5 <input type="date">.

    0 讨论(0)
提交回复
热议问题