Иван Иванов
Иван Иванов

Reputation: 90

Why my applyBindings doesn't work? Knockout

Hello I am trying simply to create input and iframe and when I paste the YouTube link the iframe should change with the new src. I have done this so far

<div class="heading">id <input data-bind="text: youtubeLink"/></div>
<iframe id="player" type="text/html" width="444" height="250" frameborder="0" data-bind="attr: { src: linkEmbed }"></iframe>

And in the script:

function MyViewModel() {
    this.youtubeLink = ko.observable('https://www.youtube.com/watch?v=4UNkmlCKw9M');
    this.linkEmbed = ko.pureComputed({
        read: function () {
                var extract = this.youtubeLink().replace("/watch?v=", "/embed/");
                console.log(extract)
                return extract;
        },
        write: function (value) {
                 this.youtubeLink();
        },
        owner: this
    });
}
ko.applyBindings(MyViewModel());

This works exactly as I want but the video wont change if I paste another link in the input.

I am using this from knockout documentation: http://knockoutjs.com/documentation/computed-writable.html

Upvotes: 1

Views: 1553

Answers (2)

CarComp
CarComp

Reputation: 2016

TLDR: jQuery hides knockout bind errors.

Another thing that breaks it....

jQuery is known to catch exceptions and hide them. I had to step through knockout-debug.js AND THEN jquery.js until i got to a part that looks like this (around line 3600)

// Only normal processors (resolve) catch and reject exceptions
    process = special ?
        mightThrow :
            function() {
            try {
                mightThrow();
            } catch ( e ) {

wouldn't you know it... I put a watch on (e) an here was what I found hidden in there:

Error: Unable to process binding "text: function(){return ko.toJSON(vm.model(),null,2) }"
Message: Multiple bindings (if and text) are trying to control descendant bindings of the same element

Upvotes: 0

Roy J
Roy J

Reputation: 43881

You have several problems:

  1. You don't call new on your model, but you wrote it as a constructor
  2. You use text binding instead of value binding for your input
  3. Your computed's write doesn't assign, but you don't need it anyway

Once you correct those, it works.

function MyViewModel() {
    var model = {};
    model.youtubeLink = ko.observable('https://www.youtube.com/watch?v=4UNkmlCKw9M');
    model.linkEmbed = ko.pureComputed(function () {
        var result = model.youtubeLink().replace("/watch?v=", "/embed/")
        return result;
    });
    return model;
}
ko.applyBindings(MyViewModel());

http://jsfiddle.net/ueoob7ne/2/

Upvotes: 3

Related Questions