Search code examples
knockout.jsrequirejsamd

Accessing Knockout component DOM from required AMD viewModel


I load my Knockout component this way:

ko.components.register("example", {
    viewModel: {require: "widgets/example"},
    template:  {require: "text!widgets/example.html"}
});

with example.js (extremely simplified):

"use strict";

define(["knockout"], function(ko) {

    function ExampleWidgetViewModel(params) {

        this.editedText = ko.observable("Example");
    }

    return ExampleWidgetViewModel;
});

and example.html:

<div id="example-dlg", data-bind="text: editedText"></div>

The component is called as usual as <example></example> and everything works perfectly. But I want to access the DOM to remove the need of the id in the template. Tried the method from the documentation changing example.js to be:

"use strict";

define(["knockout"], function(ko) {

    function ExampleWidgetViewModel(params, componentInfo) {

        this.editedText = ko.observable("Example");
    }

    return {createViewModel: ExampleWidgetViewModel};
});

But it complains that editedText is not found. Same problem with other variations like this:

"use strict";

define(["knockout"], function(ko) {

    function creaExample(params, componentInfo) {
        let ExampleWidgetViewModel = (params) => {

             this.editedText = ko.observable("Example");
        }
        return ExampleWidgetViewModel;
    }
    return {createViewModel: creaExample};
});

Could you provide a working example? Thanks!


Solution

  • Nothing better than asking for help to find a solution... I was wrongly calling the view model. The correct example.js file is:

    "use strict";
    
    define(["jquery", "knockout"], function($, ko) {
    
        function factory(params, componentInfo) {
            function ViewModel() {
    
                // To show how to access the component external div
                console.log($(componentInfo.element.firstChild).attr("id"));
    
                // To show it can correctly access parameters
                this.editedText = params.oneParameter;
            }
            return new ViewModel();
        }
        return {createViewModel: factory};
    });