Ad

HTML With Knockout SPA Attempt With Components, Bindings Not Working

I'm trying to make an SPA website with knockout and requirejs from websites I've seen and tutorials, in order to split up the website so it isn't a single gigantic thing. At one point I'm expecting to see:

My first name is: Bryan

But instead I'm getting:

My first name is: function c(){if(0<arguments.length)return c.tb(c[E],arguments[0])&&(c.ga(),c[E]=arguments[0],c.fa()),this;a.l.oc(c);return c[E]}

Starting with my index.thml:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <title>asdf</title>
</head>
<body>
   <mainview></mainview>

   <!-- global imports -->
   <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
   <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.min.js"></script>
   <script type='text/javascript' src="./index.js"></script>
</body>
</html>

My index.js:

"use strict";

requirejs.config({
baseUrl: '',
paths: {
    knockout: 'https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min',
    text: 'https://cdnjs.cloudflare.com/ajax/libs/require-text/2.0.12/text.min'
}
});

ko.components.register(
  'mainview', 
  {
    require: './indexViewModel'
  }         
);

ko.applyBindings();

indexViewModel.js:

"use strict";

define(['knockout', 'text!./indexViewModel.html'], function(ko, htmlString) {
  function indexViewModel(params)
  {
    var self = this;
    self.firstName = ko.observable('Bryan');
  }

  return { viewModel: indexViewModel, template: htmlString };
});

Finally my indexViewModel.html:

<div>
    <p>input name: <input data-bind="value: firstName"></input></p>
    <p>My first name is: <span data-bind='text: firstName'></span></p>
</div>

All this gives the result I stated above.

Now if I change firstname to firstName(), then it initially comes up right, but if I change the input, nothing happens.

Ad

Answer

ok, with more digging and googling, I happened upon the solution. I don't get the details, but it's requirejs and knockoutjs are colliding some how

Because on my index.html, I import knockout and I have knockout setup as a requirejs parameter from the config.

I found this Issue loading knockout components view model using requireJS that clued me in.

ok so I made these changes:

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Battlestations Character Generator</title>
  </head>
  <body>


    <mainview></mainview>

    <!-- global imports -->
    <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.min.js"></script>
    <!-- no more knockout reference here -->
    <script type='text/javascript' src="./index.js"></script>
  </body>
</html>

now my index.js:

"use strict";

requirejs.config({
    baseUrl: '',
    paths: {
        knockout:     'https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min',
        text: 'https://cdnjs.cloudflare.com/ajax/libs/require-text/2.0.12/text.min'
    }
});

// "app main()"
requirejs(['knockout'], function(ko) {
    var self = this;

    ko.components.register(
        'mainview', 
        {
            require: './indexViewModel'
        }         
    );

    ko.applyBindings();
});

and changed <input></input> to <input />, although that changed nothing, but if that's "good practice", I'll go with it.

after those changes, reload, all works, and changing the input changes the <span> right after it.
yay!

Ad
source: stackoverflow.com
Ad