J'apprends AngularJS. J'ai rencontré quelque chose que je ne peux pas expliquer, et je ne peux trouver aucune explication (ou solution).
J'ai une simple application AngularJS et j'essaie de lier un <span contenteditable="true">
à une valeur, mais cela ne fonctionne pas. PAR EXEMPLE:
<!-- Works as expected -->
<input data-ng-model="chunk.value"></input>
<!-- Shows value, but doesn't bind - changes not reflected in model -->
<span contenteditable="true">{{chunk.value}}</span>
<!-- This is empty -->
<span contenteditable="true" data-ng-model="chunk.value"></span>
Comment puis-je faire en sorte que la dernière plage utilise la liaison bidirectionnelle, de sorte que la modification de sa valeur mette à jour chunk.value et vice versa?
ng-bind ! Utilisez ng-bind pour une liaison unidirectionnelle dans "span".
Veuillez vous référer ici pour un exemple: https://docs.angularjs.org/api/ng/directive/ngBind
Votre ligne serait donc: <span contenteditable="true" ng-bind="chunk.value"></span>
J'espère que cette aide
Faire ng-model
travailler avec contenteditable <span>
éléments, utilisez une directive personnalisée:
app.directive('contenteditable', ['$sce', function($sce) {
return {
restrict: 'A', // only activate on element attribute
require: '?ngModel', // get a hold of NgModelController
link: function(scope, element, attrs, ngModel) {
if (!ngModel) return; // do nothing if no ng-model
// Specify how UI should be updated
ngModel.$render = function() {
element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
};
// Listen for change events to enable binding
element.on('blur keyup change', function() {
scope.$evalAsync(read);
});
read(); // initialize
// Write data to the model
function read() {
var html = element.html();
// When we clear the content editable the browser leaves a <br> behind
// If strip-br attribute is provided then we strip this out
if (attrs.stripBr && html === '<br>') {
html = '';
}
ngModel.$setViewValue(html);
}
}
};
}]);
Usage:
<span contenteditable ng-model="userContent">Change me!</span>
<p>{{userContent}}</p>
Pour plus d'informations, voir
ngModelController
Référence API - Exemple de contrôle personnaliséangular.module('customControl', ['ngSanitize'])
.directive('contenteditable', ['$sce', function($sce) {
return {
restrict: 'A', // only activate on element attribute
require: '?ngModel', // get a hold of NgModelController
link: function(scope, element, attrs, ngModel) {
if (!ngModel) return; // do nothing if no ng-model
// Specify how UI should be updated
ngModel.$render = function() {
element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
};
// Listen for change events to enable binding
element.on('blur keyup change', function() {
scope.$evalAsync(read);
});
read(); // initialize
// Write data to the model
function read() {
var html = element.html();
// When we clear the content editable the browser leaves a <br> behind
// If strip-br attribute is provided then we strip this out
if (attrs.stripBr && html === '<br>') {
html = '';
}
ngModel.$setViewValue(html);
}
}
};
}]);
[contenteditable] {
border: 1px solid black;
background-color: white;
min-height: 20px;
}
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/angular-sanitize/angular-sanitize.js"></script>
<body ng-app="customControl">
<span contenteditable ng-model="userContent">Change me!</span>
<hr>
Content={{userContent}}
</body>
ng-model
N'est pas destiné à être utilisé avec span
. Si vous en avez absolument besoin, vous pouvez écrire une directive personnalisée pour cela. Cette directive créera un écouteur keydown,keyup
Sur contentEditable
span
et mettra à jour le modèle de portée (dans $apply()
). Cela liera le contenu de l'étendue au modèle.
J'ai rapidement créé un plunker pour vous. Vérifiez-le. Il synchronise le contenu <span>
Avec le modèle de portée. Ouvrez la console du navigateur pour voir la mise à jour du modèle de portée chaque fois que vous tapez quelque chose.
En ajoutant ng-model-options="{ getterSetter: true }"
comportement à un élément qui a ng-model
y est attaché. Vous pouvez également ajouter ng-model-options="{ getterSetter: true }"
à un <form>
, qui activera ce comportement pour tous les <input>s
à l'intérieur.
Un exemple montre comment utiliser ngModel
avec un getter/setter
: page de démonstration
ngModel
ne fonctionnera pas comme l'a souligné @VtoCorleone. ngModel docs
The ngModel directive binds an input,select, textarea (or custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive.
Vous pouvez consulter la directive contentable .
Sinon, solution de contournement potentielle: avoir une fonction qui est appelée. Cette fonction met ensuite à jour le $scope.chunk.value
dans votre contrôleur. Et il prendrait en charge le contenu des autres éléments lors de la mise à jour de la liaison.
Je ne suis pas sûr de l'apparence ou des fonctionnalités exactes que vous recherchez, mais mettez-les simplement dans un <textarea>
et le style pour ressembler à un <span>
(pas de bordure ni d'arrière-plan, etc.). Ensuite, quand il est dans focus
, vous ajoutez un style supplémentaire pour savoir qu'il peut être modifié. Cette façon vous permettrait d'utiliser le ng-model
tel qu'il est destiné à être utilisé. Voici une implémentation de base de cette approche: Plunker