Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

support for custom binders when calling ac.done #182

Closed
wants to merge 4 commits into from

6 participants

@caridy
Owner

having a structure like this at the mojit level:

/mojitName
   /binders/foo.js
   /binders/bar.js
   /views/index.mu.html
   /views/baz.mu.html

you can invoke ac.done in your action to customize which binder to use:

ac.done(data, { 
    view: {
        name: "index",
        binder: "foo"
    }
});

or more customization

ac.done(data, { 
    view: {
        name: "baz",
        binder: "bar"
    }
});

in general, if there is a file defining a binder, you can now attach it to any view.

@redonkulus

+1 to this, as its sorely needed to serve different binders across different devices (mobile vs desktop). What is the status / ETA on this?

@isao

:+1: look great. ran it through the secondary tests (pull-job 23) but it got kicked out for jslint errors.

@mridgway mridgway was assigned
@mridgway

@drewfish Does the new resource store affect any of the code in this PR? I saw that the notes mentioned that it made this feature possible, so should this be re-implemented to make use of the new functionality in the RS?

@drewfish
Owner

I think it should still work with the new resource store. The new store continues to set 'binder-url', 'binder-path', 'binder-module', 'binder-yui-sorted' in the mojit instance.

@FabianFrank

When looking at @redonkulus use case, I think it would be good that when we have
index.js
index.iphone.js

Mojito automatically serves the index.iphone.js binder. People shouldn't have to implement this logic by themselves. We should have this kind of automatic file picking for devices across the framework, I think.

@drewfish
Owner

@FabianFrank That's how Mojito works today. If you say ac.done(..., {view: {name: 'index'}}); it will use the index.iphone.js binder for iphone users.

What the original request wants is a way to use a binder that doesn't match the name of the action.

@caridy caridy closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 24, 2012
  1. @isao
  2. @drewfish
Commits on Jun 2, 2012
  1. @caridy
  2. @caridy

    adding support for custom binders when calling ac.done. if the binder…

    caridy authored
    … is defined with a different name than the view, you can specify the custom binder as part of the ac.done meta data. this facilitate the reuse of views and binders.
This page is out of date. Refresh to see the latest.
View
33 source/lib/app/addons/ac/output-adapter.common.js
@@ -92,8 +92,37 @@ YUI.add('mojito-output-adapter-addon', function(Y, NAME) {
// We want to know the view name, id, and binder used later so make sure
// "meta" is up-to-date
meta.view.name = meta.view.name || action;
- // TODO: Use a different binder
- meta.view.binder = meta.view.binder || meta.view.name;
+ // a custom binder was invoke
+ if (meta.view.binder) {
+ if (instance.views[meta.view.binder]) {
+ // merging the selected view with the precomputed binder structure.
+ // keep in mind that this is the binder path/filename, and based on that
+ // we can capture the rest of the meta data from the binders collection.
+ // Something like this:
+ /*
+ bar/foo: {
+ 'binder-url': '/App/binders/bar/foo.js',
+ 'binder-path': '/path/to/mojits/App/binders/bar/foo.js',
+ 'binder-module': 'MojitBinderBarFoo',
+ 'binder-yui-sorted': {}
+ }
+ */
+ Y.log('Customizing binder "' + meta.view.binder + '" for view "' + meta.view.name + '"', 'mojito', 'qeperf');
+ // TODO: I don't like to have this whitelist of binder-* properties, but since
+ // there is not a clear distintion on how to resolve a custom binder, there
+ // is not much we can do. Remember that the actual binder lookup is based on
+ // the binder path rather than the binder module name.
+ Y.mix(instance.views[meta.view.name], (instance.views[meta.view.binder] || {}),
+ true, ['binder-url', 'binder-path', 'binder-module', 'binder-yui-sorted'], 0, false);
+ }
+ else {
+ Y.log ('Trying to attach an undefined binder with name='+meta.view.binder, 'error', NAME);
+ }
+ }
+ else {
+ // default binder is based on the view name.
+ meta.view.binder = meta.view.name;
+ }
mojitView = instance.views[meta.view.name];
if (!meta.view.id) {
meta.view.id = Y.guid();
View
60 source/lib/tests/autoload/app/addons/ac/output-adapter-tests.common.js
@@ -193,6 +193,66 @@ YUI.add('mojito-output-adapter-addon-tests', function(Y, NAME) {
},
+ 'custom binder is used for render': function() {
+ var vrRendered;
+ // mock view renderer
+ var VR = Y.mojito.ViewRenderer;
+ Y.mojito.ViewRenderer = function(engine) {
+ A.areSame('engine', engine, 'bad view engine');
+ return {
+ render: function(d, type, v, a, m, more) {
+ vrRendered = true;
+ A.areSame(data, d, 'bad data to view');
+ A.areSame('t', type, 'bad mojitType to view');
+ A.areSame(meta, m, 'bad meta to view');
+ A.isString(meta.view.id, 'bad id assigned to view');
+ A.areSame(myBinderModuleName, meta.binders[meta.view.id].name, 'bad binder module name');
+ A.isFalse(more);
+ }
+ };
+ };
+ var ac = { app: { config: {} } };
+ var data = {};
+ var myBinderModuleName = 'MojitBinderFoo';
+ var meta = {
+ view: {
+ name: 'viewName',
+ binder: 'binderName'
+ }
+ };
+ ac._adapter = {
+ done: function() {
+ A.fail('done should not be called, the view renderer should be calling it');
+ }
+ };
+ ac.command = {
+ instance: {
+ type: 't',
+ views: {
+ viewName: {
+ engine: 'engine',
+ 'content-path': 'path'
+ },
+ binderName: {
+ 'binder-url': '/virtual/path/binders/foo.js',
+ 'binder-path': '/path/to/mojits/App/binders/foo.js',
+ 'binder-module': myBinderModuleName,
+ 'binder-yui-sorted': {}
+ }
+ }
+ }
+ };
+ new Y.mojito.addons.ac.core(null, null, ac);
+
+ ac.done(data, meta, false);
+
+ A.isTrue(vrRendered, 'view render never called');
+
+ // replace mock
+ Y.mojito.ViewRenderer = VR;
+
+ },
+
'config children params are stripped': function() {
var doneCalled;
var children = {
Something went wrong with that request. Please try again.