Javascript AngularJS-ng模型在contenteditable上失败<;span>;

Javascript AngularJS-ng模型在contenteditable上失败<;span>;,javascript,angularjs,html,contenteditable,angularjs-ng-model,Javascript,Angularjs,Html,Contenteditable,Angularjs Ng Model,我在学AngularJS。我遇到了一些我无法解释的事情,也找不到任何解释(或解决方案) 我有一个简单的AngularJS应用程序,我试图将一个绑定到一个值,但它不起作用。例如: <!-- Works as expected --> <input data-ng-model="chunk.value"></input> <!-- Shows value, but doesn't bind - changes not reflected in model

我在学AngularJS。我遇到了一些我无法解释的事情,也找不到任何解释(或解决方案)

我有一个简单的AngularJS应用程序,我试图将一个
绑定到一个值,但它不起作用。例如:

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

{{chunk.value}}

如何使最后一个span使用双向绑定,以便编辑其值更新chunk.value,反之亦然?

ngModel不会像@VtoCorleone指出的那样工作

你可以看一看这本书

否则,可能的解决方法是:使用一个被调用的函数。然后,该函数更新控制器中的
$scope.chunk.value
。当绑定被更新时,它会处理其他元素的内容


我不确定您想要的是什么样的外观或功能,但只需将其放在
中,并将其样式设置为
(无边框或背景等)。然后,当它处于
焦点时
,您可以添加其他样式,以知道它可以编辑。这种方式将允许您按照预期使用的方式使用
ng型号
。以下是此方法的基本实现:

ng model
不适用于
span
。如果您确实需要,您可以为此编写自定义指令。此指令将在
contentEditable
span
上设置
keydown、keydup
侦听器,并更新作用域模型(在
$apply()
内)。这将跨内容绑定到模型


我很快为你创建了一个。过来看。它将
内容同步到范围模型。打开浏览器控制台,在键入内容时查看作用域模型更新。

通过向附加了
ng model
的元素添加
ng model options=“{getterSetter:true}”
行为。您还可以将
ng model options=“{getterSetter:true}”添加到
中,这将为其中的所有
s
启用此行为

示例显示了如何将
ngModel
getter/setter
一起使用:
ng bind!在“span”中使用ng bind进行单向绑定

请参阅此处的示例:

所以你的路线是:


希望此帮助

要使
ng模型
与可编辑的
元素一起工作,请使用自定义指令:

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);
        }
      }
    };
}]);
[内容可编辑]{
边框:1px纯黑;
背景色:白色;
最小高度:20px;
}

改变我!

Content={{userContent}}
span元素为只读。对于ng模型的双向绑定,您需要一些输入。你打算如何在第二个跨度中更改内容?html中怎么会有只读内容?我计划通过模型或用户单击并键入来更改它-因此
contenteditable=“true”
如何在范围或标签上输入数据?您可以更改它们的值,但它们正在读取您给它们的任何值。1)点击F12打开开发控制台,就在本页的这里。2) 键入
$('span')。文本('potato')并点击回车键。3) 请注意更新的内容。您是否希望您的用户使用开发人员工具来更改文本?用户可以编辑某些DOM元素,但span不是其中之一。这就是他所说的只读的意思。你为什么要这么做?范围是从范围的模型读取的。为什么会有另一个作用域属性监听span的model属性?@VtoCorleone我们当然不需要从模型到span的绑定(它已经被处理好了)。只要在span内容更改时更新范围模型就可以解决我们的问题。很抱歉,我没有这样做-如何调用此函数?我应该使用jQuery
.on('blur',…)
还是什么?我的目标是没有任何样式-这就是为什么我尝试使用span。我正在寻找可编辑的文本段落,例如类似记事本的东西。“块”是一段文字中的一段文字。我可能会把它作为一个点击事件,附加到某种保存或更新按钮上。我认为这就是AngularJS擅长的?我不能强迫我的用户每次更新都点击一次——这太可笑了!如果你想要记事本之类的东西,为什么不使用文本区而不是span?要么我完全误解了您的意图,要么您需要在开始Angular.ng-bind是单向绑定之前更多地了解HTML和JS基础知识。使用contenteditable更改范围中的内容不会更改基础模型。
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>