Git Product home page Git Product logo

deftjs's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

deftjs's Issues

Usage instructions?

Looks like a promising framework, but the README contains no instructions for best-practice on how to integrate it with either Sencha Touch 2 or ExtJS 4. Please provide an install/usage section with detailed instructions.
my HEAD looks like this (using Phonegap):
Somehow Sencha Touch is autoloaded (using the microloader?), so DeftJS should be loaded only after the Ext namespace has been defined. Please advice.

    <!-- resources -->
    <script type="text/javascript" src="resources/javascript/i18n.js">
    </script>
    <script type="text/javascript" src="resources/javascript/locale_da.js">
    </script>
    <!--
    <script type="text/javascript" src="lib/deftjs/build/deft-debug.js">
    </script>    
    -->
    <!-- phonegap -->
    <script id="cordova" type="text/javascript" src="cordova-1.8.0.js"></script>
    <!-- The line below must be kept intact for Sencha Command to build your application -->
    <script id="microloader" type="text/javascript" src="sdk/microloader/development.js"></script>        
    <script type="text/javascript">
        // document.addEventListener("deviceready", app.mainLaunch, false);
    </script>    
</head>

A user defined constructor on a View will break the Deft.mixin.Controllable

A user defined constructor on a View will break the Deft.mixin.Controllable from being able to hook into the object construction.

See the most basic constructor added on Lines 24-28 of the Controllable.js Spec
https://gist.github.com/3033957

Chances are this is breaking because of the "Ext.Function.createSequence" chain it's creating, but then being overridden the user defined constructor.

Question? Is there a way to hook or force call this when a view has a constructor?

One possible solution is to provide/expose a method similar to how Ext.util.Observable does. This would give us the best of both worlds, the current (automated) method for %80 of the time, and a manual way for those %20 edge cases.

Reference:
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.util.Observable
"this.mixins.observable.constructor.call(this, config);"

View's `getController()` should be valid when View constructor executes

The ViewController should generally be the injection target for state and services. In the rare cases where you need access to those View Controller properties in a view (generally just for initializing the store associated with a Grid, Tree or DataView), they should be accessible within the view's initComponent() method by way of getController().

However, in Deft v0.6.7 and earlier, getController() is not valid until after the View's constructor has been executed. When initComponent() is triggered by a View's constructor, getController() is not be available.

Moving forward, getController() should be valid when the View constructor method executes.

The new setup sequence should be:

  1. The View instance is created, and setup begins...
  2. The View Controller specified via the View's controller annotation should be created and fully instantiated.
  3. The getController() method referencing that View Controller instance should be added to the View instance.
  4. The View instance's constructor method should be executed.
  5. The View Controller instance's controlView() method should be called, passing the fully instantiated View instance.
  6. The View Controller instance's init() method should be fired once the View has rendered / initialized.

Once 'live events' (see issues #4 and #5) has been implemented, steps 5 and 6 will be revisited and simplified.

init() never called on superclass

Ext.define( 'App.controller.AbstractViewController', {
  extend: 'Deft.mvc.ViewController',  

  init: function(){
    //never called
    return this.callParent( arguments ); 
  }
});

Ext.define( 'App.controller.ConcreteViewController', {
  extend: 'App.controller.AbstractViewController',  

  init: function(){
    //called
    return this.callParent( arguments ); 
  }
});

Inject does not update config property for sencha touch 2.0

My component hierarchy is App.ListMap <- App.Map <- Ext.Map. Injecting the geo attribute creates a new local property (this.geo) but does not update the config property (this.getGeo()) defined in Ext.Map. Calling this.getGeo() inside ListMap should return the injected value.

Ext.define('App.ListMap',  {
  extend: 'App.Map',
  mixins: [ 'Deft.mixin.Injectable' ],

  inject: {
    geo: 'geolocation'
  },

  ...
}
Deft.Injector.configure({
  geolocation: {
    className: 'Ext.util.Geolocation',
    parameters: [{
      autoUpdate: false,
      allowHighAccuracy: true
    }]
  },
});

Registered ComponentReferences/ComponentSelectors are not cleaned up on Sencha Touch

Deft.mvc.ViewController::onViewDestroyed() is never called on Sencha Touch (due to the differing destruction lifecycle path). Consequently, the cleanup logic implemented there is not executed on that platform.

Proposed solution: move the clean-up logic to the destroy() method. This will require any subclasses to call this.callParent(), but that should be fairly well understood as a standard practice when overriding destroy() method.

Ext.log undefined for sencha touch 2.0

I get the following error when trying to include deft.js in a sencha touch 2.0 project.

Uncaught TypeError: Property 'log' of object #<Object> is not a function

Uncaught TypeError: Cannot read property 'buffer' of undefined

After Updating to the latest version of deft I am getting the following error.

Uncaught TypeError: Cannot read property 'buffer' of undefined
Ext.define.doFiresencha-touch-all.js:17366
Ext.define.firesencha-touch-all.js:17316
Ext.define.doDispatchEventsencha-touch-all.js:22436
Ext.define.dispatchsencha-touch-all.js:59135
Ext.define.publishsencha-touch-all.js:59209
Ext.define.doFiresencha-touch-all.js:17389
Ext.define.firesencha-touch-all.js:17316
Ext.define.doDispatchEventsencha-touch-all.js:22436
Ext.define.dispatchEventsencha-touch-all.js:22417
Ext.define.doFireEventsencha-touch-all.js:26678
Ext.define.fireEventsencha-touch-all.js:26637
Ext.define.constructor

My code causing the issue.

Ext.define("App.controller.Activities", {
  extend: "Ext.app.Controller",
  mixins: [ 'Deft.mixin.Injectable' ],

  inject: {
    geo: 'geolocation'
  },

  config: {
    refs: { 
      index: 'activitiesindex'
    },

    control: {
      index: {
        initialize: 'viewPrivateList'
      }
    }
  },

  viewPrivateList: function(){
    ...
  }, 
});

Sencha code throwing the error:

            options = listener.options;            

            ...

            if (!firingFn) {
                firingFn = boundFn;

                if (options.buffer) {
                    firingFn = Ext.Function.createBuffered(firingFn, options.buffer, scope);
                }

                if (options.delay) {
                    firingFn = Ext.Function.createDelayed(firingFn, options.delay, scope);
                }

                listener.firingFn = firingFn;
            }

I'm not sure if this is a Sencha or Deft issue but It only breaks after upgrading Deft to the latest.

As a developer extending custom defined 'view' classes, Deft JS should recognize multiple controller(s) defined in the inheritance chain

An Ext JS view having a Deft Controllable mixin results in only the final superclass controller being exposed.

We used a workaround in the code here, but probably too specific for general use. There is some tracing functionality that you could use to see what's happening.
cnstaging@971dc02#L0R668
cnstaging@98176eb

I can provide a simple example of real code if needed... but its more complex looking at Ext, than just pseudo for this.

'Views'
[10] Ext.panel.Panel > [20] Workspace > [30] Embedded
[10] Ext.panel.Panel > [20] Workspace > [40] Window

'Controllers'
[n/a] Ext.panel.Panel > [50] Workspace > [60] Embedded
[n/a] Ext.panel.Panel > [50] Workspace > [70] Window
"> = extends"

20, 30, 40 all reference a different controller. The current version of Deft JS results in only the controller defined from [20] to be exposed.

50,60,70 bring in new abilities/functions depending on the role. In the current version of Deft JS, it results in only [50] being the responding getController()

Do you have plans to support this type of feature?

Bug with Injector: eager fail when singleton

using deftjs 0.6.4

browser : chrome 18 on windows 7.

was doing:

Deft.Injector.configure({
    preferences:  {
        className: 'MyApp.preferences.Preferences',
        eager: true
    },
    ...
});

created MyApp.preferences.Preferences as singleton

Ext.define("MyApp.preferences.Preferences",{

    singleton : true,

  ...

});

Got this in Chrome console:

ext-dev.js:7941Uncaught Error: [Ext.create] MyApp.preferences.Preferences' is a singleton and cannot be instantiated

Add require statements for Ext framework dependencies.

As of v0.8, Deft JS has dependencies on Ext framework classes that are not part of the ext.js, ext-dev.js and ext-debug.js builds.

Prior to the changes introduced in this commit, certain Deft JS features would break in deployment builds because associated Ext class overrides would silently fail. Now, the associated loader dependency errors will be shown in the error console.

By accurately reflecting Ext framework dependencies, the individual JS class files can be used in combination with the Sencha build tool by power users to generate a truly minified build (omitting any unused classes).

The deft.js and deft-debug.js builds should only be used in combination with the ext-all.js, ext-all-debug.js or ext-all-dev.js builds of Ext JS.

In all other cases, the loader should be configured to resolve Deft to the individual source files in src/js/Deft.

Controlling a view that does not exists yet

Let's say that I have a Grid with record and a contextmenu that appera at rightclick on a row. Controlling the actions of the contextmenu
from the Grid's ViewController would not work because will throw this error
Uncaught Deft.mvc.ViewController.addComponentReference(): Error locating component: no component(s) found matching 'contextmenuusers menuitem[action=add]'.

....
   control:{
...
     cmUsersEdit:{
            selector:'contextmenuusers menuitem[action=edit]',
            listeners:{
                click:function (menuitem) {
....

Which is the best way to do treat this type of situation.

Controllable mixin should add a 'getController()' method?

We've been considering enhancing the Controllable mixin to add a getController() accessor to the view that would provide access to the corresponding view controller. Using this a view would be able to access its view controller to obtain references to any objects that were injected there and allowing both view and view controller to interact with the same injected prototype instance. Currently the controller has to access the store via whatever component it might have been assigned to (not ideal).

Thoughts?

Add Listeners to multiple components in ViewController

I have a form that has two submit buttons, one in the upper right hand corner and another at the bottom.

      { 
        xtype: 'button',
        action: 'submit',
        ui: 'action',
        align: 'right'
      },
      ...
      { 
        xtype: 'button',
        action: 'submit',
        ui: 'action'
      },

Currently the only way to add a listener to both the buttons is to give it a unique identifier and create two separate listeners.

    titleSubmitButton: {
      selector: 'button#edit_title_submit',
      listeners: {
        tap: 'onSubmitTap'
      }
    },
    formSubmitButton: {
      selector: 'button#edit_form_submit',
      listeners: {
        tap: 'onSubmitTap'
      }
    },

It'd be nice if there was a way to add a listener to both buttons using a single selector.

    listeners: {
      selector: 'button[action=submit]',
      tap: 'onSubmitTap'
    },

Observer unit test failing for Ext JS 4.0.7

The following test:

Deft.mvc.ViewController Observer creation should attach listeners to observed objects using nested property declaration.

is failing with:

TypeError: Object [object Object] has no method 'fireEvent'

For Ext JS 4.0.7.

To replicate:

  • Uncomment the Ext JS 4.0.7 CDN reference in SpecRunner.html, and comment out the Ext JS 4.1.1 CDN reference.
  • Run the specs.

Append subclass injections

It would be be nice if DeftJS allowed me to append injections to those declared in a superclass.

For example, say I have a BaseViewController that declares:

inject: [ 'someObject' ]

I then extend that in MyConcreteViewController and declare:

inject: [ 'someOtherObject' ]

The problem seems to be that the list of injections overwrites the superclass instead of appending to it. I was assuming it would work like the other configuration properties appear to, where I can declare config: values and rather than overwrite, they add onto those declared in a superclass.

So, while it's not a huge issue to declare inject: [ 'someObject', 'someOtherObject' ] in the child class, it does reduce the advantages of inheritance a bit.

DeftJS views dont work with Sencha Architect

to create a view with Sencha Architect and use the controllable mixin, Within Archiect I have created an override to include the mixin:

Ext.define('article.view.override.Preview', {
requires: 'article.view.Preview',
mixins: [ 'Deft.mixin.Controllable', 'Deft.mixin.Injectable' ]
}, function() {
Ext.override(article.view.Preview, {
});
});

The mixin
targetClass.prototype.constructor = Ext.Function.createSequence(targetClass.prototype.constructor, function() {....
code is reached, but the body never gets executed, and the controller is not created.

if I move the mixins: [ 'Deft.mixin.Controllable', 'Deft.mixin.Injectable' ] into the article.view.Preview class it works .

Downloadable version on deftjs.org is incorrect

Hi,

The version you link to download on the deftjs.org site is very out of date. It references 0.1.1. It took me about half an hour to figure out why Deft.mvc.ViewController was failing to load, until I realised the download was incorrect.

Cheers,
Josh

Introduce Promise-aware function chaining convenience methods.

Developers new to Promises and Deferreds often are curious how to use these in the context of operation queues, where a set of functions needs to be run in sequence, in parallel, or as a pipeline.

@briancavalier posted an excellent GitHub Gist demonstrating how to achieve this with his library when.js: https://gist.github.com/2713087/

It would be helpful to provide similar convenience methods were provided as part of the Deft JS library, adapted to match the Deft JS Promise API.

Specifically, these methods would be implemented as new static methods of a Deft.promise.Chain class / package (with alternate class name Deft.Chain).

Deferreds should silently ignore completion attempts after cancellation.

Currently a Deferred will throw an Error when resolve(), reject(), update() or cancel() are called after it has been cancelled.

This should change, because it would otherwise require pending state changes above all calls to these methods. Pragmatically, the real expectation is that a cancelled Deferred / Promise will silently ignore subsequent attempts to complete it. In all other cases an Error should still be thrown when resolve(), reject(), update() or cancel() is called on a completed (but not cancelled) Deferred / Promise.

Deft.Logger.log(), etc. should call Ext.log() in Ext JS

Deft.Logger checks for the existence of Ext.Logger to differentiate between Ext JS (where logging is done only through Ext.log()) and Sencha Touch (where logging is done through Ext.Logger).

Unfortunately, Ext.Logger.log() is defined in some versions of Ext JS, with all methods mapped to Ext.emptyFn (an empty function).

Refactor this to use Ext.getVersion( 'extjs' ) rather than making the determination based on the existence of Ext.Logger.log().

Listening for viewport

I want to creeate a controller that listens also what happens on viewport like this

Ext.define('Users.controller.Main', {
    extend: 'Deft.mvc.ViewController',

    requires: ['Users.view.UsersViewport'],

    control: {
        myviewport     : {
            selector: 'viewport'
        },
....

The problem is that deftjs code raises an error "Uncaught Ext.Error: Error locating component: no component found matching 'viewport'. "

This happens because when parsing control settings it calls locateComponent

  locateComponent: function(id, config) {
    var matches, view;
    view = this.getView();
    if (id === 'view') {
      return view;
    }
    if (Ext.isString(config)) {
      matches = view.query(config);
      if (matches.length === 0) {
        Ext.Error.raise({
          msg: "Error locating component: no component found matching '" + config + "'."
        });
      }
      if (matches.length > 1) {
        Ext.Error.raise({
          msg: "Error locating component: multiple components found matching '" + config + "'."
        });
      }
      return matches[0];
    } else if (Ext.isString(config.selector)) {
      matches = view.query(config.selector);

The problem is here: view.query(config.selector);. The view is the viewport and queries for himseld. There is no match. That is not Ok.

In ExtJS 4 MVC, listening for viewport work Ok, and generates also a getter for this viewport.

Support passing configs to the ViewController when creating a View

It is currently awkward to initialize ViewControllers because they are created indirectly via Views.

As opposed to controller-oriented frameworks, where the View Controller is initialized and created, pushed onto a presenting Window or View Controller and then subsequently creates its associated UI components, Ext JS and Sencha Touch are UI component-oriented frameworks, where the UI components are created directly and UI containers are populated via component descriptors (JSON-esque Objects populated with xtypes and configuration values). Consequently, with Deft JS, View Controllers are created in response to the creation of Views (rather than the other way around).

There is currently no way to pass an initializing configuration object to the ViewController's constructor for a Controllable View because the View Controller instance is created behind-the-scenes. To remedy this, we need a controllerConfig config that can be specified in addition to the controller annotation on a Controllable View.

Consider:

Ext.define('ExampleViewController', {
  extend: 'Deft.mvc.ViewController',
  config: {
    value: null
  }
});

Ext.define('ExampleView', {
  extend: 'Ext.Container',
  alias: 'widget.exampleView'      
  mixins: ['Deft.mixin.Controllable'],
  controller: 'ExampleViewController'
});

and

Ext.create('ExampleView', {
  controllerConfig: {
    value: 'expected value'
  }
});

or

Ext.widget( 'exampleView', {
  controllerConfig: {
    value: 'expected value'
  }
});

In either case, the ExampleViewController's constructor will be passed the controllerConfig initialization object when called, and in this example the value config will be initialized with "expected value". The getValue() method in that ViewController instance will return "expected value".

Throw a more useful error when unable to resolve an nonexistent class.

When the Injector is asked to resolve an identifier that references nonexistent (or non-required) class, the changes in Issue #11 cause it fail with an error related to availability of classReference.singleton rather than letting the developer know that the class was not found.

Current error message:

TypeError: 'null' is not an object (evaluating 'classDefinition.singleton')

It should instead tell the developer the class definition wasn't found.

Add better error handling and reporting for this situation.

Controller Issues with 0.67

I've built a nice desktop app OS using ExtJS 411.

It works great.

My plan was to use DeftJS to load my module instances into my windows dynamically.

That works, but..
My desktop is designed in a way that it can have multiple instances of the same module in different windows.

In order to avoid the duplicate id conflict, I figured I could hack something as follows;

init: function() {
    var idPrx = this.view.id;
    debugger;
    this.control[idPrx + '-modButton'] = {
        click : 'myClickFunc'
    }

},

Now this works in the sense that I can instantiate a window and get no errors, but, the event doesn't fire as I would have expected it.

However, if I spawn a second window. I get a nasty error. My desktop OS actually has a nice Error / Msg system, so it generated the following:

ID: Error1
Date: 2012-08-17
Time: 17:22:45
Error Message: Error locating component: no component found with an itemId of 'module2-1-AppModule-modButton'.
sourceMethod: "locateComponent"
sourceClass: "Deft.mvc.ViewController"

Now, to understand this in context, my first window is named 'module-2-1-AppModule' and the button is named 'module-2-1-AppModule-modButton'.

The second window is named 'module-2-2-AppModule'. the button is named 'module-2-2-AppModule-modButton'.

So, I've not had a chance to dive into the inner workings of Deft, but I suspect it don't like the way I'm using it.

But to me, and my understanding of Deft. I want to be able to inject any module I wish and any amount and ensure that I'm not dealing with duplicate IDs issues when I have multiple instances.

I have a few workaround ideas, but hoping that I can stick to DeftJS.

Any ideas?

MVC Routing/Navigation

DeftJs.org mentions a feature "Navigation - support for hierarchical views, route-aware" on its road map.
Will this feature enable routing in Ext Js MVC apps?
What is the status of the feature? (in a month, year, on back burner :))
Currently routing is only available in Touch, and by the looks of it, Sencha is not in a hurry to port it to Ext Js...

Thanks a lot!

Errors raised in promise callbacks should be logged to the console

I understand that the Promise/A spec requires that exceptions raised in callback do not halt execution. However, silenting them completely leads to a lot of confusion, especially before one realizes that Deft is catching all their JS errors.

Errors can be logged to the console without crashing the execution thread. For example, in Chrome:

console.error(error.stack)

will give the same output as an uncatched error, with the "correct" stack trace. I don't know for other browsers, but even if the full stack cannot be provided, a notice should definitely be issued.

Errors do not propagate on class creation

Hi,

When a class is created through the Deft.mixin.Controllable mixin, if the class creation fails a generic error is thrown. Would this not be more useful to provide information related to why the class creation failed?

For example if you configure a store but the proxy fails to create, it's difficult to debug the exact point of failure. I'm happy to provide a pul request to fix this issue, I just need to know whether this is a valid request.

Cheers,
Josh

configs are never injected for Ext JS UI components

Apparently, to initialize configs, Ext JS's AbstractComponent implementation just brute-force Ext.apply()'s the configuration object passed to the constructor onto the object instance itself, whereas Sencha Touch's AbstractComponent uses the Ext JS class system's initConfig() method.

Consequently, Ext JS's components never call initConfig(). Without that method call, Deft JS injection of configs never occurs.

Sencha might change that behavior in the future to make it more consistent across these two platforms in the future. This is going to require writing a platform and version specific workaround.

`Deft.Promise::reduce()` handling for `initialValue` is broken.

The logic nested in a closure within this method incorrectly assumes that arguments corresponds to the original function invocation. Consequently, the intended check for the presence of an initialValue parameter is wrong.

This functionality was broken when issue #6 was resolved.

Promise does not behave as it should?

I would expect to see a log "THIS SHOULD BE SHOWN" as a correct behavior. the promise object should be resolved.
the code will only work if the resolve will occur after the promise.then.

var defr = new Deft.promise.Deferred();
        var promise = defr.getPromise();


        defr.resolve();          

        promise.then(function(){

            console.log("THIS SHOULD BE SHOWN");

        }); 

How to get a reference to the app instance?

In Sencha's controllers, the application is passed in, and set to controller.application.

How do I get a reference to the application from a Deft ViewController? Or do I not want to do that?

How do I fire an app-wide event?

Thanks

Neil

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.