可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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.
回答2:
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/
回答3:
Even shorter than other code samples is the following:
ko.extenders.withDefault = function(target, defaultValue) {
target.subscribe(function(input) {
if(!input) target(defaultValue)
});
return target
};
With the initiation
ko.observable().extend({ withDefault: "some Default" })
回答4:
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.
回答5:
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>
回答6:
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.
回答7:
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.. :)