web-dev-qa-db-fra.com

Éditer le contenu en place Édition

Lorsque vous utilisez ng-repeat quel est le meilleur moyen de pouvoir éditer du contenu?

Dans ma situation idéale, l'anniversaire ajouté serait un lien hypertexte; lorsque cela sera tapé, il affichera un formulaire de modification - identique au formulaire d'ajout actuel avec un bouton de mise à jour.

Live Preview (Plunker)

HTML:

<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="utf-8">
    <title>Custom Plunker</title>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script>
      document.write('<base href="' + document.location + '" />');
    </script>
    <script src="app.js"></script>
    <link href="//netdna.bootstrapcdn.com/Twitter-bootstrap/2.2.0/css/bootstrap-combined.min.css"
    rel="stylesheet">
  </head>
<body ng-app="birthdayToDo" ng-controller="main">
    <div id="wrap">

      <!-- Begin page content -->
      <div class="container">
        <div class="page-header">
          <h1>Birthday Reminders</h1>
        </div>
            <ul ng-repeat="bday in bdays">
                <li>{{bday.name}} | {{bday.date}}</li>
            </ul>

           <form ng-show="visible" ng-submit="newBirthday()">
            <label>Name:</label>
            <input type="text" ng-model="bdayname" placeholder="Name" ng-required/>
            <label>Date:</label>
            <input type="date" ng-model="bdaydate" placeholder="Date" ng-required/>
            <br/>
            <button class="btn" type="submit">Save</button>
        </form>
      </div>

      <div id="Push"></div>
    </div>

    <div id="footer">
      <div class="container">
        <a class="btn" ng-click="visible = true"><i class="icon-plus"></i>Add</a>
      </div>
    </div>
    </body>

App.js:

var app = angular.module('birthdayToDo', []);

app.controller('main', function($scope){ 

    // Start as not visible but when button is tapped it will show as true 

        $scope.visible = false;

    // Create the array to hold the list of Birthdays

        $scope.bdays = [];

    // Create the function to Push the data into the "bdays" array

    $scope.newBirthday = function(){

        $scope.bdays.Push({name:$scope.bdayname, date:$scope.bdaydate});

        $scope.bdayname = '';
        $scope.bdaydate = '';

    };
});
54
Jess McKenzie

Vous devriez mettre le formulaire à l'intérieur de chaque noeud et utiliser ng-show et ng-hide pour activer et désactiver l’édition, respectivement. Quelque chose comme ça:

<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>

Les points clés ici sont:

  • J'ai changé de contrôle ng-model à la portée locale
  • Ajoutée ng-show à form afin que nous puissions l'afficher lors de l'édition
  • Ajout d'un span avec un ng-hide pour masquer le contenu lors de l'édition
  • Ajout d'un ng-click, qui pourrait être dans n'importe quel autre élément, qui bascule editing en true
  • Modifié ng-submit pour basculer editing en false

Voici votre Plunker mis à jour .

71
Caio Cunha

Je recherchais une solution de montage en ligne et j’ai trouvé un plunker qui semblait prometteur, mais cela n’a pas fonctionné pour moi immédiatement. Après quelques manipulations du code, je l'ai fait fonctionner. Félicitations à la personne qui a fait l’effort initial de coder cette pièce.

L'exemple est disponible ici http://plnkr.co/edit/EsW7mV?p=preview

Voici le 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'
  };
});

Modèle de directive:

<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>

Pour l'utiliser, il suffit d'ajouter de l'eau:

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

MISE À JOUR:

Une autre option consiste à utiliser le readymade Xeditable pour AngularJS:

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

26
John P

J'ai modifié votre plunker pour le faire fonctionner via angular-xeditable :

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

C'est une solution courante pour l'édition en ligne - vous créez des hyperliens avec editable-text directive qui bascule en <input type="text"> tag:

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

Pour la date j'ai utilisé editable-date directive qui bascule en html5 <input type="date">.

7
vitalets

Comme il s’agit d’une fonctionnalité courante, il est recommandé d’écrire une directive à cet effet. En fait, quelqu'un l'a déjà fait et en a ouvert la source. J'ai utilisé la bibliothèque editablespan dans l'un de mes projets et cela a fonctionné à la perfection, vivement recommandé.

4