Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with AMD #25

Closed
mariusfilipowski opened this issue Jun 13, 2013 · 7 comments
Closed

Integration with AMD #25

mariusfilipowski opened this issue Jun 13, 2013 · 7 comments
Assignees

Comments

@mariusfilipowski
Copy link
Contributor

Please provide support for AMD with requirejs without using globals für jQuery and Knockout.

@ghost ghost assigned hfjallemark Jul 17, 2013
@hfjallemark
Copy link

Here is the commanding I am currently testrunning in my local environment:

// By: Hans Fjällemark and John Papa
// https://github.com/CodeSeven/KoLite

(function (factory) {
  if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
    factory(require("knockout"), exports);
  } else if (typeof define === "function" && define["amd"]) {
    define(["knockout", "exports"], factory);
  } else {
    factory(ko, ko);
  }
}(function ( ko, exports ) {
  if (typeof (ko) === undefined) {
    throw 'Knockout is required, please ensure it is loaded before loading this validation plug-in';
  }

  exports.command = function (options) {
    var
      self = ko.observable(),
      canExecuteDelegate = options.canExecute,
      executeDelegate = options.execute;

    self.canExecute = ko.computed(function () {
      return canExecuteDelegate ? canExecuteDelegate() : true;
    });

    self.execute = function (arg1, arg2) {
      // Needed for anchors since they don't support the disabled state
      if (!self.canExecute()) return

      executeDelegate.apply(this, [arg1, arg2]);
    };

    return self;
  };

  exports.asyncCommand = function (arg1, arg2) {
    var
      self = ko.observable(),
      canExecuteDelegate = arg1.canExecute || arg2,
      executeDelegate = arg1.execute || arg1,

      completeCallback = function () {
        self.isExecuting(false);
      };

    self.isExecuting = ko.observable();

    self.canExecute = ko.computed(function () {
      return canExecuteDelegate ? canExecuteDelegate(self.isExecuting()) : !self.isExecuting();
    });

    self.execute = function (arg1, arg2) {
      // Needed for anchors since they don't support the disabled state
      if (!self.canExecute()) return

      var args = []; // Allow for these arguments to be passed on to execute delegate

      if (executeDelegate.length >= 2) {
        args.push(arg1);
      }

      if (executeDelegate.length >= 3) {
        args.push(arg2);
      }

      args.push(completeCallback);
      self.isExecuting(true);
      executeDelegate.apply(this, args);
    };

    return self;
  };

  wrapAccessor = function (accessor) {
    return function () {
      return accessor;
    };
  };

  ko.bindingHandlers.command = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
      var
        value = valueAccessor(),
        commands = value.execute ? { click: value } : value,

        isBindingHandler = function (handler) {
          return ko.bindingHandlers[handler] !== undefined;
        },

        initBindingHandlers = function () {
          for (var command in commands) {
            if (!isBindingHandler(command)) {
              continue;
            };

            ko.bindingHandlers[command].init(
                element,
                wrapAccessor(commands[command].execute),
                allBindingsAccessor,
                viewModel
            );
          }
        },

        initEventHandlers = function () {
          var events = {};

          for (var command in commands) {
            if (!isBindingHandler(command)) {
              events[command] = commands[command].execute;
            }
          }

          ko.bindingHandlers.event.init(
              element,
              wrapAccessor(events),
              allBindingsAccessor,
              viewModel);
        };

      initBindingHandlers();
      initEventHandlers();
    },

    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
      var commands = valueAccessor();
      var canExecute = commands.canExecute;

      if (!canExecute) {
        for (var command in commands) {
          if (commands[command].canExecute) {
            canExecute = commands[command].canExecute;
            break;
          }
        }
      }

      if (!canExecute) {
        return;
      }

      ko.bindingHandlers.enable.update(element, canExecute, allBindingsAccessor, viewModel);
    }
  };
}));

@acornejo
Copy link
Contributor

Is there a reason this hasn't made it to master yet?

I've been trying to use kolite in a requirejs project, and it seems impossible to do without monkey patching it myself.

Has anyone been able to get kolite working with a shim (without patching it for amd support).

For the record, I tried the following without success:

    "shim": {
      "knockout": {
          "exports": "ko"
       },
      "knockout.activity": {
        "deps": ["knockout"],
        "exports": "ko.activity"
      },
      "knockout.command": {
        "deps": ["knockout"],
        "exports": "ko.command"
      },
      "knockout.dirtyFlag": {
        "deps": ["knockout"],
        "exports": "ko.dirtyFlag"
      },

Before the shim, I declared made sure that the path config points to the javascript files for knockout, knockout.activity, etc..

Doing a google search reveals a lot of other people with the same problem, but no workable solution.

@hfjallemark
Copy link

I have it for the commanding, will get that in master today.

hfjallemark pushed a commit that referenced this issue Nov 27, 2013
hfjallemark pushed a commit that referenced this issue Nov 27, 2013
@hfjallemark
Copy link

@acornejo it's in master for the commands and dirty flag now. Please test it out. Will have a look at activity when I get some more time.

@acornejo
Copy link
Contributor

Thanks! I will test later today.

Regarding the activity indicator, would you accept a pull request for that (which also replaces the jquery plugin for font awesome?)

@acornejo
Copy link
Contributor

@hfjallemark I tested command and dirty flag, they both work fine.

I also created a pull request #39 to wrap activity with amd definitions, and to use font-awesome.

The pull-request contains a more detailed description, but in addition to simplifying the logic this will make kolite lighter in dependencies (font-awesome will be used if it exists, but it can also be used without it by using custom css classes which can be controlled through options).

Let me know what to do to get this pull-request accepted, since I would like to avoid maintaining my own fork.

Thanks for everything Hans.

Alex

@hfjallemark
Copy link

AMD support for activity fixed in #39.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants