سؤال

I am trying to write a custom binding to replace "/n" with "<br />" within a "<p>" element.

I understand the concept more or less, but I'm stuggling to get it going. Can anyone suggest where I'm going wrong. I don't really want to use a computed observable, as I want to keep the real value using "/n" rather than "<br />".

ko.bindingHandlers.nl2br = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var field = valueAccessor();
        field.replace(/\n/g, '<br />');
        $(element).val(field)
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var field = valueAccessor();
        field.replace(/\n/g, '<br />');
        $(element).val(field)
    }
};
هل كانت مفيدة؟

المحلول

TL;DR Answer

ko.bindingHandlers.nl2br = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var field = ko.utils.unwrapObservable(valueAccessor());
        field = field.replace(/\n/g, '<br />');
        ko.bindingHandlers.html.update(element, function() { return field; });
    }
};

Full Answer

First things first, the replace call should probably be:

field = field.replace(/\n/g, '<br />');

Otherwise the new string gets discarded.

Apart from that, I wouldn't recommend setting the element value like that directly. Rely on the existing handlers (that presumably are well tested in various browsers) to do the heavy lifting. See R.P. Niemeyer's blog post on the subject (specifically item 3).

You can use either the the text binding which will literally render "<br />" or (if you trust the input!) the html binding if you want to render a newline for the <br />. The latter looks like this:

ko.bindingHandlers.nl2br = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var field = ko.utils.unwrapObservable(valueAccessor());
        field = field.replace(/\n/g, '<br />');
        ko.bindingHandlers.html.update(element, function() { return field; });
    }
};

ko.applyBindings({ description: ko.observable("This is\nSparta!") });
p, pre { background-color: #dde; margin: 4px 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<strong>Text version in &lt;p&gt;:</strong>
<p data-bind="text: description"></p>
<hr />
<strong>Text version &lt;pre&gt;:</strong>
<pre data-bind="text: description"></pre>
<hr />
<strong>NL2BR version in &lt;p&gt;:</strong>
<p data-bind="nl2br: description"></p>

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top