knockout.js - data-bind text default value

2020-08-09 05:56发布

In knockout.js I have a very standard field that looks like this:

<label data-bind="text: JobTitle"></label>

What I'd like is to have a default value specified in here if the text value is null, for example "No Job Title Specified".

Is this possible to do in knockout.js?

Thanks.

7条回答
The star\"
2楼-- · 2020-08-09 06:10

I ran into this when returning data for a table, but only having some columns sortable.

<tr data-bind="foreach: ArrAsrColumnHeaders">
  <th class="sortable koJson" data-bind="
     css: {active: ((typeof(isActive) != 'undefined') ?  isActive : '')}
      , text: text
      , attr:{href: ((typeof(jsonClick) != 'undefined') ?  jsonClick : '')}">
  </th>
</tr>

This says that, for each column in the table's header, add the class 'active' if 'isActive' is defined and set to true, but don't freak out if it isn't there. The same goes for adding a 'href' attribute.

Disclaimer: I don't understand knockout well enough to know the limitations of this approach, but this worked for me in my case, whereas, the more straightforward approach of css: {active: isActive() || ''} threw errors.

查看更多
做自己的国王
3楼-- · 2020-08-09 06:12

To show the data in the input field, the easiest way is...

<input title="Stage" value="Default Entry Goes Here" readonly="readonly" type="text" id="stage" class="form-control" data-bind="value: model.stage ||text-input: Default Entry Goes Here">

It errors but it works.. :)

查看更多
啃猪蹄的小仙女
4楼-- · 2020-08-09 06:13

You can do it like this:

<label data-bind="text: JobTitle() != undefined && JobTitle() != null ? JobTitle() : 'No Job Title Specified'"></label>

With the undefined control, you can check whether you have that function or not when you are loading the page for the first time.

查看更多
Rolldiameter
5楼-- · 2020-08-09 06:13

It might be useful to have a default value for display purposes only, instead of applying extenders which always return a default value.

With this, properties of your model remain empty, which is better for example when it comes to validation (checking for empty properties) or sending data back to the server (you might not want to send back this default value).

You could use the custom binding in the following example, which is based on the text binding, which renders a supplied default text or - if not supplied (you could adjust this to your needs of course):

ko.bindingHandlers['textWithDefault'] = {
    'init': function() {
      return { 'controlsDescendantBindings': true };
    },
    'update': function (element, valueAccessor) {
        var value, defaultValue;
        var options = ko.utils.unwrapObservable(valueAccessor());
        if (options !== null && typeof options == "object") {
            value = ko.unwrap(options['text']);
            defaultValue = ko.unwrap(options['default']);
        } else {
            value = options;
        }
        defaultValue = defaultValue || '-';

        ko.utils.setTextContent(element, value || defaultValue);
    }
};

function ExampleModel() {
  this.value = 'Sample text';
  this.observableValue = ko.observable('More sample text');
  this.emptyValue = '';
  this.emptyObservableValue = ko.observable();
};

ko.applyBindings(new ExampleModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<div data-bind="textWithDefault: value"></div>
<div data-bind="textWithDefault: observableValue"></div>
<div data-bind="textWithDefault: emptyValue"></div>
<div data-bind="textWithDefault: emptyObservableValue"></div>
<div data-bind="textWithDefault: { text: emptyValue, default: 'Custom empty value' }"></div>
<div data-bind="textWithDefault: { text: emptyObservableValue, default: 'Another custom empty value' }"></div>

查看更多
可以哭但决不认输i
6楼-- · 2020-08-09 06:22

So I'm guessing you want a real default value and not just a placeholder text. Here's a way to do that with an extender;

ko.extenders.defaultIfNull = function(target, defaultValue) {
    var result = ko.computed({
        read: target,
        write: function(newValue) {
            if (!newValue) {
                target(defaultValue);
            } else {
                target(newValue);
            }
        }
    });

    result(target());

    return result;
};

var viewModel = function() {
   this.someValue = ko.observable().extend({ defaultIfNull: "some default" });
};

ko.applyBindings(new viewModel());

http://jsfiddle.net/madcapnmckay/aTMpp/

Hope this helps.

查看更多
手持菜刀,她持情操
7楼-- · 2020-08-09 06:27

The shortest / easiest way is probably:

<label data-bind="text: JobTitle()||'No Job Title Specified'"></label>

Working example:

var ViewModel = function() {
    this.jobTitle = ko.observable();
};
 
ko.applyBindings(new ViewModel());
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.liveExample input { font-family: Arial; }
.liveExample b { font-weight: bold; }
.liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
.liveExample select[multiple] { width: 100%; height: 8em; }
.liveExample h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class='liveExample'>   
    <p>Job Title: <input data-bind='value: jobTitle' /></p> 
    <h2 data-bind="text: jobTitle()||'No Job Title Specified'"></h2>  
</div>

Or JS Fiddle: http://jsfiddle.net/735qC/43/

查看更多
登录 后发表回答