1

The textbox binds fine, but the src attribute in the embed tag doesn't bind at all. Why?

http://jsfiddle.net/pscr43sc/1/

<input type='text' data-bind='value: 123'/>
<embed data-bind="attr: {src: 'http://google.com'}" />
Jeroen
  • 60,696
  • 40
  • 206
  • 339
Ray Cheng
  • 12,230
  • 14
  • 74
  • 137

1 Answers1

1

The problem is not that the src attribute is not being bound by Knockout: that bit is working perfectly, as you can tell from this screenshot of your fiddle with the dev tools open:

dev tools

The src attribute gets set correctly by KnockoutJS.

You are experiencing (a variant of) this issue where the browser doesn't like the fact that src is dynamically changed on such elements. Mentioned workarounds mostly come down to re-creating the entire element, which is pretty easy to do with KnockoutJS.

Here's a "naive" example that allows for some "dirty" KnockoutJS code, as in that it contains some DOM manipulation inside the view:

function RootViewModel() {
  var self = this;
  self.link = ko.observable("//placehold.it/50");
  self.embedHtml = ko.computed(function() {
    return "<embed src='" + self.link() + "' />"; // Might need some sanitation on "link()"
  });
}

ko.applyBindings(new RootViewModel());
pre { background: white; padding: 10px; color: #333; font: 11px consolas; border: 1px solid #ddd; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<div data-bind="html: embedHtml"></div>
<hr>Change link: <input data-bind="value: link">
<hr>Debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

If you change the link (e.g. change "50" to "200") and blur the input field, you'll see the change on the embed tag.

Note that the above is actually remixed from (and the solution should be attributed to @RPNiemeyer) another SO answer, which also goes on to suggest an alternative. With that alternative you'd create a custom binding handler that clones the embed node on view model updates, changes the src attribute, and then replaces the original node with the clone in the DOM. The upside there is that you have no DOM code inside your view model. The answer links to this jsfiddle for an example.

Community
  • 1
  • 1
Jeroen
  • 60,696
  • 40
  • 206
  • 339