55 votes

Angular JS - Éditer le contenu en place Éditer

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

Dans ma situation idéale, l'anniversaire ajouté serait un hyperlien; lorsqu'il sera tapé, un formulaire de modification s'affichera - tout comme le formulaire d'ajout actuel avec un bouton de mise à jour.

Aperçu en direct (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="http://stackoverflow.com//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 = '';

    };
});
 

71voto

CaioToOn Points 9069

Vous devriez mettre theform à l'intérieur de chaque nœud et l'utilisation ng-show/ng-hide activer désactiver la modification. Quelque chose comme ceci:

<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 sont ici:

  • J'ai changé les contrôles ng-model de l'étendue locale
  • Ajouté ng-show de form donc on peut le montrer lors de l'édition
  • Ajout d'un span avec un ng-hide afin de masquer le contenu lors de l'édition
  • Ajout d'un ng-click, qui pourrait être dans n'importe quel autre élément, qui permet de basculer editing de true
  • Changé ng-submit pour basculer editing de false

Ici est votre jour Pluker.

26voto

John P Points 5891

Je cherchais une édition en ligne de la solution et j'ai trouvé un plunker qui semblait prometteur, mais il ne fonctionne pas pour moi hors de la boîte. Après quelques retouches avec le code que j'ai eu de travail. Bravo à la personne qui a fait l'effort initial pour le code de 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'
  };
});

La Directive modèle:

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

Utiliser simplement 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 est d'utiliser le readymade Xeditable pour AngularJS:

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

7voto

vitalets Points 590

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

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

C'est une solution commune pour la modification en ligne - vous creale de liens hypertextes avec des editable-textdirective qui permet de basculer en <input type="text"> balise:

<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 permet de basculer en html5 <input type="date">.

4voto

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X