【问题标题】:angular ngModel style角度 ngModel 风格
【发布时间】:2018-08-02 15:03:26
【问题描述】:

是否可以在输入标签的属性 ngModel 中设置值的样式?

例子:

<input class="input" type="text" [(ngModel)] = "myService.text">

假设文本的值为'28 packages',我可以把28加粗吗?

【问题讨论】:

  • 在纯 HTML/CSS 中仅对输入内容的一部分进行样式设置似乎是不可行的。
  • 在javascript中可行吗?
  • 也许你可以在输入的顶部加上 &lt;div&gt; 来做一些事情(被 &lt;div&gt; 隐藏)。当用户点击 div 时,您实际上是关注隐藏的输入。当用户键入文本时,您捕获它并使用它来填充 div。通过这样做,您将能够在 28 周围的 div 中放置一些 &lt;span class=""&gt;,然后使用 CSS 设置样式。
  • 文本包是否一直存在?
  • 不,文本包并不总是存在,它可能会改变,取决于类型。

标签: html angular


【解决方案1】:

所以,如果我理解正确,您希望在值为 28 时将其设为粗体?

是的,您可以使用带有三元表达式的 ng-class

.bold{
font-weight:600;
}
&lt;input type="text" ng-class="myService.text == '28 ? 'bold' : '''" class="input" ng-model="myService.text" /&gt;

【讨论】:

  • 不,我不希望它在值为 28 时变为粗体,我希望值为粗体并且值后面的文本为 normal.example: 15 项目
  • @Observablerxjs 我认为将不同的font-weight 分配给相同的 HTML 输入是可能的。如果是这样,您将需要一些巧妙的技巧
【解决方案2】:

这与角度无关,而是与 CSS 相关的问题。

您不能在 HTML/CSS 中仅对输入的一部分进行样式设置,因此您将无法在 Angular 中进行设置。

相反,您可以使用隐藏在 div 后面的输入。这个想法是,当用户单击 div 时,您实际上是集中输入。当用户键入文本时,您捕获输入内容并用它填充 div,最终在包数周围添加&lt;span class"highlight"&gt;

我为你准备了一个纯 CSS/JS 的stackblitz。如果你愿意,你可以调整它的角度。

相关代码:

HTML

<span id="hiddenSpan">This is the hidden div. Click it and start typing</span>

<div>
  <label for="in">The real input</label>
  <input id="in" type="text">
</div>

JS

const input = document.getElementById('in')
const hiddenSpan = document.getElementById('hiddenSpan')

function onInputChanged() {
  let text = input.value

  const regex = new RegExp('(\\d+) packages')
  let result = regex.exec(text)

  if(result) {
    hiddenSpan.innerHTML = '<span class="highlight">'+result[1]+'</span> packages'
  } else {
    hiddenSpan.innerHTML = text
  }
}

// Capture keystrokes.
input.addEventListener('keyup', onInputChanged)

// Focus the input when the user clicks the pink div.
hiddenSpan.addEventListener('click', function() {
  input.focus()
})

CSS

#hiddenSpan {
  background-color: pink;
}

.highlight {
  font-weight: bold;
  background-color: greenyellow;
}

注意:缺点是闪烁的插入符号不再可见。如果你想模拟一个,你可以看看this resource

【讨论】:

    【解决方案3】:

    无法将文本&lt;input&gt; 字段的某些部分设置为粗体。但是,您可以使用 contenteditable div 代替文本 &lt;input&gt; 字段。在 contenteditable div 中,您可以使用其他 HTML 标记,例如 &lt;strong&gt;,以根据您的喜好设置文本的某些部分。

    我创建了一个名为 contenteditableModel 的 Angular 指令(查看 StackBlitz demo here),您可以使用它对 contenteditable 元素执行双向绑定,如下所示:

    <div class="input" contenteditable [(contenteditableModel)]="myService.text"></div>
    

    该指令使用正则表达式自动检查输入文本中的数字,并将它们包围在&lt;strong&gt; 标记中以使其变为粗体。例如,如果您输入“28 个包”,则divinnerHTML 将被格式化为这样(使“28”变为粗体):

    <strong>28</strong> packages
    

    这是指令中用于执行格式化的代码:

    var inputElement = this.elementRef.nativeElement;
    inputElement.innerHTML = inputElement.textContent.replace(/(\d+)/g, "<strong>$1</strong>");
    this.change.emit(inputElement.textContent);
    

    您可以将&lt;strong&gt; 标记更改为其他内容(例如,&lt;span style="text-decoration: underline"&gt;,如果您希望文本带有下划线而不是粗体)。

    执行格式化时,用户的文本光标位置会意外重置回contenteditable div 的开头。为了解决这个问题,我使用了 2 个函数(getOriginalCaretPositionrestoreCaretPosition)来存储用户的原始光标位置,然后在执行文本格式化后恢复位置。这两个功能有点复杂,它们与 OP 的问题并不完全相关,所以我不会在这里详细介绍它们。想了解更多可以私信我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-07
      • 2018-12-31
      • 1970-01-01
      • 2015-10-27
      • 2018-12-14
      • 1970-01-01
      • 2019-09-16
      • 2013-05-20
      相关资源
      最近更新 更多