Material Design Lite:如何以编程方式重置浮动标签输入文本

Material Design Lite: How to programatically reset a floating label input text

我目前正在使用 knockout.js 和 Material Design Lite 构建单页应用程序。

我有一个允许创建(和持久化)新实体的表单。第一次使用表单时,浮动标签输入工作正常。但是在那之后,如果我通过敲除可观察对象重置字段的值(即将字段值设置为“”以便能够输入另一个新实体的值)浮动标签不会重置:浮动标签仍然浮动在字段上方,而它应该在字段本身中以灰色显示而不再浮动。

请注意,如果我手动输入该字段,添加 space,删除 space 并退出该字段,则重置行为有效。

以下是代码的重要摘录:

表单是根据 Material Design Lite 定义的(参见 http://www.getmdl.io/components/index.html#textfields-section "text with floating label")

<form>
  <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
    <input class="mdl-textfield__input" type="text" id="field1" data-bind="value: field1" />
    <label class="mdl-textfield__label" for="field1">Field1 floating label</label>
  </div>
</form> 

在淘汰赛方面我有这个代码:

function MyViewModel() {
  var self = this;
  self.field1 = ko.observable();
  ....
  self.resetForm = function () {
      self.field1("");
  }
  ....

在我的 JS 中,我创建了我的 ViewModel

var vm = new MyViewModel()

并且,当我想创建一个新实体时,我在这个视图模型上调用

vm.resetForm();

为了重置字段。该字段已正确设置为空值,但未触发浮动布局行为(回到初始状态)。

谢谢

您的问题已讨论 here。您需要一个自定义绑定处理程序,以便在绑定值更改时向输入周围的 div 添加和删除 类(特别是 is-dirty)。

自定义绑定处理程序有点麻烦,但它实际上会让您的 HTML 更干净。我在下面为您准备了一个作为示例,尽管它肯定会有所改进。

This is a good read 关于这个主题。

ko.bindingHandlers.mdlFloatingInput = {
    init: function (element, valueAccessor, allBindingsAccessor, data, context) {
        var $el = $(element),
            $enclosingDiv = $('<div>').insertAfter($el),
            $label = $('<label>'),
            params = valueAccessor();
        $el.attr('id', params.id);
        $label.attr('for', params.id).text(params.label);
        $el.addClass('mdl-textfield__input');
        $label.addClass('mdl-textfield__label');
        $enclosingDiv.addClass("mdl-textfield mdl-js-textfield mdl-textfield--floating-label").append($el).append($label);
        
        ko.bindingHandlers.value.init(element, function () { return params.value; }, allBindingsAccessor, data, context);
    },
    update: function (element, valueAccessor, allBindingsAccessor, data, context) {
        var params = valueAccessor(),
            value = params.value();
        ko.bindingHandlers.value.update(element, function () { return params.value; }, allBindingsAccessor, data, context);
        $(element).parent()[value ? 'addClass' : 'removeClass']('is-dirty');
    }
};

function MyViewModel() {
    var self = this;
    self.field1 = ko.observable('');
    self.resetForm = function () {
        self.field1("");
    };
}

var vm = new MyViewModel();

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//storage.googleapis.com/code.getmdl.io/1.0.5/material.min.js"></script>
<link rel="stylesheet" type="text/css" href="//storage.googleapis.com/code.getmdl.io/1.0.5/material.indigo-pink.min.css">

<form>
    <input data-bind="mdlFloatingInput: {label: 'Field1 floating label', value: field1, id:'field1'}" />
    <!--div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
        <input class="mdl-textfield__input" type="text" id="field2" />
        <label class="mdl-textfield__label" for="field2">Unbound floating label</label>
    </div-->
</form>
<button data-bind="click:resetForm">Reset</button>
<div data-bind="text:field1"></div>

您可以简单地使用

<yourElement>.MaterialTextfield.change();