Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load KnockoutJS custom functions with RequireJS?

I have a View Model that uses a custom observableArray function for sorting. When I try to run this it says: "...has no methods 'sortByProperty'".

How should I load the handlers.js file to make this work?

handlers.js:

define(['knockout'], function(ko) {
        'use strict';

        ko.observableArray.fn.sortByProperty = function (prop, order) {
            this.sort(function (obj1, obj2) {
                var result;
                if (obj1[prop] == obj2[prop])
                    result = 0;
                else if (obj1[prop] < obj2[prop])
                    result = -1;
                else
                    result = 1;

                return order === "desc" ? -result : result;
            });
        };

    });

viewmodel.js:

define([
        'knockout',
        'js/extends/handlers'
    ], function(ko) {
        'use strict';

        var LabelsModel = function() {
            var self = this;

            self.availableLabels = ko.observableArray();
            self.selectedLabel = ko.observable();
            self.sortBy = ko.observable(); // What field to sort by
            self.sortOrder = ko.observable(); // Sort order. asc or desc.

            // Returns the labels for the current page
            self.pagedRows = ko.computed(function() {
                // Sorts the labels
                return self.availableLabels.sortByProperty(self.sortBy(), self.sortOrder());
            });

        };

        return LabelsModel;

    });
like image 536
Sindre Avatar asked May 15 '13 09:05

Sindre


1 Answers

You have to first make sure KnockoutJS is defined, then load the plugins, and finally launch your application. This I think is how all plugins for libraries should be loaded. Here is how you can do it:

require.config({
        paths: {
        jquery: 'libs/jquery-1.9.0.min',
        ko: 'libs/knockout-2.2.1.min'
    }
});

require(['jquery', 'ko'], 
    function($, ko) {
        // ensure KO is in the global namespace ('this') 
        if (!this.ko) {
            this.ko = ko;
        };

        requirejs(['handlers'],
            function () { 
                require(['app'], 
                    function(App) { 
                        App.initialize(); 
                    }
                );
            }
        );
    }
);

I had a lot more libraries so I cut it down a bit only to JQuery and KnockoutJS, but basically you:

  1. declare where your libraries
  2. require loading them
  3. require loading the plugins for your libraries, here the handlers for KnockoutJS
  4. load your app (conveniently named... 'app' here :-). This is where you should initialize your view models and bind them to DOM elements. This is most likely the point where all libraries and plugins have been loaded.
like image 152
Jalayn Avatar answered Oct 01 '22 17:10

Jalayn