Javascript AngularJS-ng模型在contenteditable上失败<;span>;
我在学AngularJS。我遇到了一些我无法解释的事情,也找不到任何解释(或解决方案) 我有一个简单的AngularJS应用程序,我试图将一个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
绑定到一个值,但它不起作用。例如:
<!-- 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>