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.
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 = '';
};
});
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:
ng-model
à la portée localeng-show
à form
afin que nous puissions l'afficher lors de l'éditionspan
avec un ng-hide
pour masquer le contenu lors de l'éditionng-click
, qui pourrait être dans n'importe quel autre élément, qui bascule editing
en true
ng-submit
pour basculer editing
en false
Voici votre Plunker mis à jour .
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:
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">
.
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é.