在页面加载时隐藏空元素,但之后不使用knockout.js

时间:2013-12-06 13:22:59

标签: javascript jquery knockout.js

我的表格有很多输入。

我在表单中使用以下语法:<!-- ko if: PropertyName -->。我在特定字段的表单中使用此语句。这允许我隐藏未定义的值(实际上不隐藏,但从DOM中删除)。

但是,我不需要动态隐藏它们。我的意思是,当值不为空且已加载时,用户可以编辑它,用户可以清空它。在这种情况下输入消失,我不需要这个。

您能否建议我 - 如何更改我的标记以及使用哪种绑定?

<!-- ko if: IsEmptyOnLoad(Property1) -->.
<input type="text" data-bind="value: Property1" />
<!-- /ko -->

<!-- ko if: IsEmptyOnLoad (Property2) -->.
<input type="text" data-bind="value: Property2" />
<!-- /ko -->

var myModel = function() {
    var self = this;

    self.Property1= ko.observable("non-empty");
    self.Property2= ko.observable();

    //self.IsEmptyOnLoad  is not implemented, how to implement?
};

var m = new myModel();
ko.applyBindings(m);

您可以尝试使用corresponding JSFiddle

这可能很奇怪,但我确实有业务情景:

  • onload不显示任何空变量,因此在页面加载后,页面中只会加载非空变量
  • 页面加载后,用户可以编辑变量,其中一些变量可以删除(变空),但在这种情况下我不需要隐藏空变量

5 个答案:

答案 0 :(得分:1)

只需使用空update方法创建自定义绑定。您可以在页面加载时对绑定init执行任何操作(在敲除绑定时更具体)。

ko.bindingHandlers.ifOnce = {
    init: function(element, valueAccessor) {
        var observable = valueAccessor(); // get observable
        var value = observable(); // get value of observable
        var isEmpty = !value; // do whatever check you want
        // and remove element from dom if empty
        if (isEmpty) {
            element.parentNode.removeChild(element);
        }
    },
    update: function(element, valueAccessor) {
        // do nothing on update
    }
};

工作示例: http://jsfiddle.net/2FTEM/6/

让我们更进一步。您询问了如何创建IsEmptyOnLoad。您可以使用Knockout虚拟元素和一些有用的方法来完成此操作。即:ko.virtualElements.emptyNode将删除Knockout <!-- ko -->标记之间的所有内容http://knockoutjs.com/documentation/custom-bindings-for-virtual-elements.html

ko.bindingHandlers.IsEmptyOnLoad = {
    init: function(element, valueAccessor) {
        var observable = valueAccessor(); // get observable
        var value = observable(); // get value of observable
        var isEmpty = !value; // do whatever check you want
        // and remove element from dom if empty
        if (isEmpty) {
            ko.virtualElements.emptyNode(element);
        }
    },
    update: function(element, valueAccessor) {
        // do nothing on update
    }
};
ko.virtualElements.allowedBindings.IsEmptyOnLoad = true;

工作示例:http://jsfiddle.net/2FTEM/7/

答案 1 :(得分:1)

到目前为止,一个有趣的问题产生了一些创造性的答案。人们似乎对视图模型中存在逻辑的恐惧症是一种普遍的趋势。顾名思义,它应该被设计为视图和模型之间的接口。首先,我会重新考虑视图模型,就像这样;

var myModel = function() {
    var self = this;
    var property = function (content, availibility) {
        return { 
            content: ko.observable(content),
            availibility: availibility
       };
    }
    self.Property1 = property('non-empty', true);
    self.Property2 = property();
};

现在您的HTML可以很简单;

<input type="text" data-bind="visible: Property1.availibility, value: Property1.content" />
<input type="text" data-bind="visible: Property2.availibility, value: Property2.content" />

我还提供了JSFiddle的分支供您参考

更新:重新考虑简单性和最小重复次数。

答案 2 :(得分:0)

如果FirstName为空,您是否只想禁用其他字段?我无法看到隐藏第一个输入字段的方式,正如您目前正在做的那样,因为它一旦消失就不允许任何人输入名称。

如果您要停用其他字段并离开第一个字段,则可以data-bind使用disable执行以下操作并删除<!-- ko if: .... -->语句:

<input type="text" data-bind="value: FirstName" />

<input type="text" data-bind="disable: FirstName().length === 0" />

请参阅更新的小提琴:http://jsfiddle.net/2FTEM/1/

<强>更新

您可以设置一个在加载视图模型后更新的observable:IsPageLoaded,您设置为true。我在JS中添加了延迟,因此您应该在最终行更新observable后显示控件:m.IsPageLoaded(true);。您可能需要使用您的代码检查它是否有效(没有setTimeout)。

<强> HTML:

<!-- ko if: IsNotEmpty -->.
<input type="text" data-bind="value: IsNotEmpty" />
<!-- /ko --> 

<!-- ko if: IsEmpty && IsPageLoaded -->.
<input type="text" data-bind="value: ''" />
<!-- /ko --> 

<强> JS:

var myModel = function() {
  var self = this;
  self.IsPageLoaded = ko.observable(false);

  self.IsNotEmpty = ko.observable("non-empty");
  self.IsEmpty = ko.observable(true);

};

var m = new myModel();
ko.applyBindings(m);

// remove this timeout to test in your enviroment - just introduces a delay
setTimeout(function() {
    m.IsPageLoaded(true);
}, 1000);

// simply use
// m.IsPageLoaded(true);

更新小提琴:http://jsfiddle.net/2FTEM/4/

答案 3 :(得分:0)

保留模型的两个副本:加载时的版本和当前正在编辑的版本。

var m = { onload : new myModel(), 
          current : new myModel() };
ko.applyBindings(m);

绑定时,将可见性绑定到加载状态,将可编辑值绑定到当前状态:

<!-- ko if: onload.Property1 -->.
<input type="text" 
    data-bind="value: current.Property1" />
<!-- /ko -->

http://jsfiddle.net/92GzK/

答案 4 :(得分:0)

您可以创建仅在“if”语句中使用的常规变量(而不是observable)。这样,如果更新字段,“if”中的条件将不会更新:

self.Property1 = ko.observable("non-empty");
self.Property2 = ko.observable();

self.initialValue1 = self.Property1();
self.initialValue2 = self.Property2();

,绑定是:

<!-- ko if: initialValue1 -->.
<input type="text" data-bind="value: Property1" />
<!-- /ko -->
<!-- ko if: initialValue2 -->.
<input type="text" data-bind="value: Property2" />
<!-- /ko -->

在这里摆弄:http://jsfiddle.net/2FTEM/13/ 希望有所帮助