Load Viewmodel and external template to the Knockout component

Asked

Viewed 204 times

1

I’m trying to load the template and Viewmodel to a knockout component using require.js, but so far unsuccessfully.

index.html (view)

<!doctype html>
<head>
    <link href="assets/css/bootstrap.min.css" rel="stylesheet" />
    <script data-main="assets/js/app" src="assets/js/vendor/require.js"></script>
</head>
<body>
    <table_n></table_n>
</body>

menu.html (Template)

<table class="table table- bordered table-hover">
    <thead>
        <tr>
            <th align=center width=60 style="display: none">Código</th>
            <th>Título</th>
            <th>Descrição</th>
            <th>Ordem</th>
            <th>Imagem url</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: {data: ListaUsuarios()}">
        <tr>
            <td style="display: none" data-bind="text: id"></td>
            <td data-bind="text: titulo"></td>
            <td data-bind="text: descricao"></td>
            <td data-bind="text: ordem"></td>
            <td data-bind="text: caminho_imagem"></td>
        </tr>
    </tbody>
</table>

menu.js (Viewmodel)

define(['knockout', 'knockoutMapping'], function (ko, komap) {
    debugger;
    var self = this;
    debugger;
    self.filter = ko.observable('');
    self.ListaUsuarios = ko.observableArray();

    $.ajax({
        type: "GET",
        url: "http://192.168.15.3/api/menus",
        contentType: "application/javascript",
        dataType: "json",
        success: function (result) {
            var a = JSON.stringify(result);
            var observableData = komap.fromJS(result);
            var array = observableData();
            self.ListaUsuarios(array);
        }
     });
});

App.js (Initiating parameters in knockout)

(function (undefined) {
    'use strict';
    requirejs.config({
        baseUrl: './', // Raiz
        urlArgs: function (id, url) {
            return (url.indexOf('?') === -1 ? '?' : '&') + 'v=23';
        }, // Debug Cache
        deps: ['assets/js/base'],
        map: {
            '*': {
                'jQuery': 'jquery'
            }
        },
        paths: {
            // Módulos
            'jquery': 'assets/js/vendor/jquery-3.1.1',
            // Library jQuery
            'knockout': 'assets/js/vendor/knockout-3.4.2',
            'knockoutMapping': 'assets/js/vendor/knockout.mapping-latest',
            // Config
            'start': 'assets/js/start'
        },
        shim: {
            'knockoutMapping': {
                deps: ['knockout']
            }
        },
        waitSeconds: 15
    });
    // Chamando módulo principal para iniciar a aplicação
    require(['jquery'], function ($) {
        require(['start']);
    });
    requirejs.onError = function (err) {
        console.log(err.requireType);
        console.log('modules: ' + err.requireModules);
        throw err;
    };
}());

base.js (Using jQuery as a module called in Requirejs)

(function () {
    define(['jquery'], function () {
        (function ($) {
            console.info('Verificando Global jQuery...');
            if (typeof window === 'object' && typeof window.document === 'object') {
                if (!!window && !(!!window.$)) {
                    window.jQuery = window.$ = jQuery;
                }
                console.log([$, jQuery]);
            }
            var version = $().jquery;
            if (typeof define === "function" && define.amd && define.amd.jQuery) {
                console.info('jQuery: ' + version + ' $.fn.jquery: ' + $.fn.jquery);
                return window.jQuery;
            }
        }(jQuery));
    });
}());

start.js (and finally initiating the component)

define(['knockout', 'knockoutMapping'], function (ko, komap) {
    debugger;
    ko.components.register('table_n', {
        viewModel: { require: 'assets/js/component/viewmodel/menu' },
        template: { require: 'text!assets/js/component/templates/menu.html' }
    });

    ko.applyBindings();
});

And down with the sad mistakes!

inserir a descrição da imagem aqui

1 answer

0


After seeing some examples of using require.js, I understood what I was doing wrong:

The index.html, menu.html(template) files are correct, but in the menu.js (Viewmodel) I changed the first line to include the ** Jquery ** library and it was like this:

Define (['jquery', 'knockout', 'knockoutMapping'], função ($, ko, komap) {

And at the end of the file after:

Self.User List (array);

I added the Knockout Applybinds:

Ko.applyBindings ();

Before the applybindings was in the start.js file, however, as I am consulting a Webapi with ajax (which is asynchronous), it was activated before the ajax received the answer and this caused one of the errors.

In the app.js file I added a javascript library called text.js in Session Paths, this library can be found in download here. She is required to load the template, because require.js by default loads only javascript files, this generated another error.

And I also added the path to the viewmodel.js menu The modified part of the file was like this

  'Texto': 'assets/js/vendor/text',
  'Menu': 'assets/js/component/viewmodel/menu',

Remember that this should be added in Session Paths after 'knockoutMapping' and before 'start''.

The base.js file has also not changed.

And in the start.js file it was removed, as I said earlier, the applybindings and also modified the first line. Now I called Viewmodel and the model for the variables that were referenced in the 'define'. And the file was like this:

** Start js.: **

Define (['knockout', 'knockoutMapping', 'menu', 'text!Assets/js/component/ templates/menu.html'], função (ko, komap, menu, menuhtml) {
    Ko.components.register ('table_n', {
        ViewModel: menu,
        Modelo: menuhtml
    });
});

And with that the table was loaded correctly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.