16

I'm learning AngularJS. I've come across something I can't explain, nor can I find any explanation for (or solution).

I have a simple AngularJS app and I am attempting to bind a <span contenteditable="true"> to a value, but it doesn't work. EG:

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

How can I make the last span use 2-way binding, such that editing its value updates chunk.value and vice versa?

4

5 回答 5

22

ng-绑定!在 'span' 中使用 ng-bind 进行单向绑定。

请参考此处的示例:https ://docs.angularjs.org/api/ng/directive/ngBind

所以你的行将是: <span contenteditable="true" ng-bind="chunk.value"></span>

希望这有帮助

于 2015-12-08T07:36:25.067 回答
1

ng-model使用 contenteditable<span>元素,请使用自定义指令:

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);
        }
      }
    };
}]);

用法:

<span contenteditable ng-model="userContent">Change me!</span>
<p>{{userContent}}</p>

有关详细信息,请参阅


演示

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>

于 2017-12-11T18:50:24.697 回答
0

通过向附加到它ng-model-options="{ getterSetter: true }"的元素添加行为ng-model。您还可以添加ng-model-options="{ getterSetter: true }"到 a <form>,这将为其中的所有人启用此行为<input>s

示例显示如何使用ngModelgetter/setter演示 页面

于 2015-04-10T14:44:46.127 回答
0

ng-model不打算与span. 如果您绝对需要,您可以为此编写自定义指令。该指令将设置一个keydown,keyup监听器contentEditable span并更新作用域模型(在 内$apply())。这会将跨度内容绑定到模型。

我很快为你创建了一个plunker。一探究竟。它将内容同步<span>到范围模型。每当您键入内容时,打开浏览器控制台以查看范围模型更新。

于 2014-05-07T21:27:15.857 回答
0

ngModel正如@VtoCorleone 指出的那样,这不起作用。ngModel 文档

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.

你可以看看contenteditable 指令

否则,潜在的解决方法:有一个被调用的函数。然后该功能会更新$scope.chunk.value您的控制器内的内容。随着绑定的更新,它会处理其他元素的内容。

我不确定您要使用的确切外观或功能,但只需将其放在 a 中<textarea>并将其设置为看起来像 a <span>(无边框或背景等)。然后当它在 中时focus,您添加额外的样式以知道它可以被编辑。这种方式将允许您按ng-model预期使用。这是这种方法的基本实现:Plunker

于 2014-05-07T21:23:14.373 回答