How do I expose events to my plugin users?
I know that I should use:
$('#myPluginDiv').trigger('eventName', ["foo", "bar"]);
to trigger the event but I'm looking for best practices describing how to declare and invoke events in plugins.
I think you can inspect some of the most used plugins and make your own assumptions. We have no standards on this, just code convention.
Colorbox (source: https://github.com/jackmoore/colorbox/blob/master/jquery.colorbox.js) defines a prefix and some constants for the event names. It also have a function for triggering and running the callbacks.
jQuery UI (source: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js) also have a common function on the widget class for triggering events (usage: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.dialog.js), but you can see that the events are hard coded on the middle of the source, instead of constants on the top like on Colorbox.
I personally think, and do it in my own plugins, that creating constants is much better if you have a lot of events to trigger, but its not necessary if you will fire only 2 or 3 events.
A helper function is a must have and should be part of your template.
The event names I use and see around all follow the standard CamelCase e.g. beforeClose.
Some advocate the use of a prefix for events like on Colorbox's cbox_open or even click.myPlugin (see: http://api.jquery.com/on/#event-names)
Conclusion: try to follow best practices and conventions for programming in general and watch for the better examples out there.
in plugin create object litereal like
var plugin = {
show:function(){
// code for show()
}
};
Related
I am looking into using one or other method and in particular method 2. Can anyone tell me the advantages and disadavantages of using the 2nd method over the 1st.
Method 1 - ViewModel.cs
PTBtnCmd = new Command<Templates.WideButton>((btn) =>
MessagingCenter.Send<CFSPageViewModel, Templates.WideButton>(
this, "PTBtn", btn));
Method 1 - MyPage.xaml.cs (SetLang etc.. methods in this file )
MessagingCenter.Subscribe<CFSPageViewModel, Templates.WideButton>(
this, "PTBtn", (s, btn) =>
{
Utils.SetState(btn.Text, vm.PT);
SetLangVisible(btn.Text);
SetLangSelected(btn.Text);
vm.CFSMessage = Settings.cfs.TextLongDescription();
});
or
Method 2 - ViewModel.cs (SetLang etc.. methods in this file )
PTBtnCmd = new Command<string>(SetMode);
private void SetMode(string btnText)
{
Utils.SetState(btnText, PT);
SetLangVisible(btnText);
SetLangSelected(btnText);
CFSMessage = Settings.cfs.TextLongDescription();
}
Would also like to hear comments on the idea of adding methods into the ViewModel.cs code. Would it be better for these to be in another file?
The MessagingCenter
helps you keep your code decoupled. Sometimes you will find yourself in a position
that requires you create a reference between certain code, but by doing so, you have to
compromise on reusability and maintainability.
Try to use it as a last resort; usually there is
another way to achieve your desired functionality. While sending a message can be very
powerful, using it too much can really eat into your readability.
A use case example for MessagingCenter would be a case where you need to update values in multiple
parts of your app. You can subscribe to a message from multiple places and thus execute
code in multiple places when a message is received. Another use case could be if some
background process is done, it can send a message and you can then inform the user in
your UI.
I would not use the messaging in the VM layer because your VM layer can then only be used in Xamarin.Forms. Some Mvm frameworks, like mvvmlight, offer a messaging capability. I would opt for that instead as you could then reuse your VMs in Wpf, Uwp or other UI frameworks other than XF.
Also i wouldn't use the messaging like you have. If probably just use databinding and raise PropertyChanged events in the VM which the view can react to.
To pass data between VMs I'd suggest navigation params or rethinking how you are using this data in general (use some sort of service or dumb down the UI depending on how "fat" your client app must be).
Messaging center as #Andy mentioned would cause reusability issues but this does not mean that you cannot use it. My approach is wrapping it in a separate service and using it in implementation. This will let you to do two things: creating more convenient or better way to use it in accordance to your use case and an option to swap out the implementation of your messenger to any other pub-sub library (or your own impl.) if you will need to use these VMs in WPF project.
Of course using something more universal across platforms would be a great option too but it also depends on how much you are "allowed"/can use third party stuff. At least with MAUI this causes some problems, but this is for another topic.
I'm new to Backbone.js and in my recent project I need a custom validation mechanism for models. I see two ways I could do that.
Extending the Backbone.Model.prototype
_.extend(Backbone.Model.prototype, {
...
});
Creating custom model that inherit from Backbone model
MyApp.Model = Backbone.Model.extend({ ... });
I quite unsure which one is a good approach in this case. I'm aware that overriding prototype is not good for native objects but will that applies to backbone model prototype as well? What kind of problems I'll face if I go with the first approach?
You are supposed to use the second approach, that's the whole point of Backbone.Model.extend({}).
It already does your first approach + other near tricks to actually setup a proper inheritance chain (_.extend is only doing a copy of the object properties, you can look up the difference in code for Backbone's extend() and Underscore's _.extend, they are very large and not very interesting. Just extending the .prototype isn't enough for 'real' inheritance).
When I first read your question, I misunderstood and thought you were asking whether to extend from your own Model Class or directly extend from Backbone Extend. It's not your question, so I apologize for the first answer, and just to keep a summary here: you can use both approach. Most large websites I saw or worked on first extend from Backbone.Model to create a generic MyApp.Model (which is why I got confused, that's usually the name they give to it :)), which is meant to REPLACE the Backbone.Model. Then for each model (for instance User, Product, Comment, whatever..), they'll extend from this MyApp.Model and not from Backbone.Model. This way, they can modify some global Backbone behavior (for all their Models) without changing Backbone's code.
_.extend(Backbone.Model.prototype, {...mystuff...}) would add your property/ies to every Backbone.Model, and objects based on it. You might have meant to do the opposite, _.extend({...mystuff...}, Backbone.Model) which won't change Backbone itself.
If you look at the annotated Backbone source you'll see lines like
_.extend(Collection.prototype, Events, { ... Collection functions ...} )
This adds the Events object contents to every Collection, along with some other collection functions. Similarly, every Model has Events:
_.extend(Model.prototype, Events, { ... Model functions ...})
This seems to be a common pattern of making "classes" in Javascript:
function MyClass(args) {
//Do stuff
}
MyClass.prototype = {....}
It's even used in the Firefox source code.
Looking for a decent observer of the Mage_Sendfriend module, when the product is sent to a friend. I just traced it and don't see anything immediately useful. There is one dispatch written in the module, which actually fires when the send to friend form is loaded, not when it's actually submitted.
Looking at the events triggered, here are some events you might use:
controller_action_postdispatch_sendfriend_product_sendmail
controller_action_postdispatch_sendfriend
controller_action_postdispatch
And in the function you want to use for this event:
$controller = $observer->getControllerAction();
... your code here
You might have to resort to observing the model_save_after and model_save_before events, then checking $observer->getEvent()->getObject() to see if it's the Mage_Sendfriend model you're looking for.
An ugly solution, but sometimes the events just don't line up to solve a problem nicely.
Good luck! Let us know if you find anything good!
Edit: I would also suggest against observing a controller for this, though, since that isn't very modular. If a third-party module provides another interface for the Sendfriend feature, it wouldn't work with your module if you observe controller actions.
You can dispatch custom events when and where you want.
Mage::dispatchEvent('any_name_for_your_custom_event',
array('key'=>$value,'key'=>$value,'key'=>$value)); //can pass how many values you want in this array.
And in your config you just make your nodes to look for this event, and call one method from observer.
Its simple.
Backbone JS highly recommends you use jQuery. However, it doesn't do things very jQuery. For example, jQuery removes the necessity of the new operator, backbone makes heavy use of it.
On another note, I'm looking for a framework that is based more around prototypal inheritance than classical inheritance (new). jQuery doesn't fall under this category, this is just an architecture style I am leaning towards.
Are there any frameworks that use prototypal inheritance, or is it roll your own bridge pattern?
Backbone and jQuery solve different problems... Backbone essentially gives you a structure in order to make Javascript heavy apps... It gives you Models, Collections, Views and Controllers (although, based on only a day of playing with it, it feels to me like controllers are used for routing, and the views are kind of like a classic controller)
Backbone has a dependency on jQuery (or Zepto if you're that way inclined) to help it do things like AJAX requests.
You are correct - it is not very jQuery like, but it is providing you with something very different...
UPDATE
As of version 0.5.0 backbone have renamed controllers to routers, which should make things a little more obvious for folks coming from MS MVC / Rails etc...
"We've taken the opportunity to clarify some naming with the 0.5.0 release. Controller is now Router"
http://documentcloud.github.com/backbone/#Router
I fully agree with the answer provided by Paul and also would like to restate that your question is ambiguous in its essentials.
Jquery is highly dom-centric and provides you excellent facilities for operating upon the DOM. Be it changing styles, loading remote content to some portion of document, responding to browser events ... in (almost) everything the core focus is upon the DOM. For this kind of functionality, where you are operating upon document content, prototypal inheritance and more significantly the style of accessing widgets through the DOM (check out the APIs of JQueryUI) works rather well. If you identify widgets as javascript objects, then you have to keep track of the objects as well ... which you in case of the programming style followed by JQueryUI etc., you dont have to, because you can access any widget present in the DOM by navigating through the DOM structure or simply through its id (which essentially acts as a global identifier for the element).
backbone.js is altogether built for a different purpose. The very introduction clearly states that it is built upon the underlying philosophy that tying your data to the DOM is bad.
When you build an application that structured as per backbone.js conventions, you are essentially always concentrated on javascript objects which may be somehow linked to the DOM.
You are defining models that interface with server data sources, models which trigger events when the data contents are manipulated, collections which help you manage large data sets ... whatever, you are always operating on javascript objects which are not hardwired into the Document structure. For such scenario, it is more usual to think in terms of traditional object oriented model.
Once you have an object, the workflow is not much different from what you are habituated with using jQuery because backbone too, just like jQuery, advocates for the observer pattern.
So, in the same manner that you can bind event handlers to DOM elements with JQuery, you attach event handlers to custom events dispatched by models, collectors etc. So the two amalgamate well.
As far as other frameworks are concerned, you might want to checkout Knockout which provides data bindings and observables etc. and does not require you to use new keyword to create instances, rather instances are created by calling functions in ko namespace which might appeal to your tastes. KO has extensive documentation and code examples, which you can explore to decide whether it suites your tastes. I can not comment more on KO because I have limited knowledge about it, but as far as backbone.js is concerned I would very strongly recommend you not to dismiss the framework just because you dont like the way some things are implemented. It does elegantly and robustly what it is supposed to do and maintains an incredibly small footprint.
I think you suffer from a misunderstanding of prototypal inheritance and what you actually want in a framework. If you're modifying prototypes but never using the new keyword, then you're never creating new objects. If you're looking for a framework to abstract away object creation, that's another topic, though you shouldn't be afraid to use the new keyword; It's a big part of JavaScript.
You can actually use the new syntax with jQuery, and when you don't use it, jQuery is actually recalling itself again with the new syntax along with the arguments you passed to it. This is pure syntactic sugar and makes very little difference about anything.
"On another note, I'm looking for a framework that is based more around prototypal inheritance than classical inheritance (new)."
Backbone is built on prototypal inheritance through the method extend that is built into all models, collections, and views. It's quite problem free and easier to use and adds things like super - a hook into the parent's prototype - something that can be more difficult to do with just plain JS prototyping.
Backbone.js brings a codding standard for ajax driven web-apps that don't have to refresh the page in order to serve data.
jQuery brings a set of tools to help you get basic things done without worrying about the browser you're running the code in.
They have nothing in common. It's like comparing a hammer (jQuery) with a toolbox (backbone.js). The hammer is just a part of the toolbox, not the other way around.
So, yes! Backbone.js is not like jQuery.
"I'm looking for a framework that is based more around prototypal
inheritance than classical inheritance the new operator".
There is no 'classical' inheritance on Javascript. Actually there is no other standard way to prototype than using 'new' maybe jQuery just provides a method who does the 'new' inside.
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
After developing in CodeIgniter for awhile, I find it difficult to make decisions when to create a custom library and when to create a custom helper.
I do understand that both allow having business logic in it and are reusable across the framework (calling from different controller etc.)
But I strongly believe that the fact that CI core developers are separating libraries from helpers, there has to be a reason behind it and I guess, this is the reason waiting for me to discover and get enlightened.
CI developers out there, pls advise.
i think it's better to include an example.
I could have a
class notification_lib {
function set_message() { /*...*/}
function get_message() {/*...*/}
function update_message() {/*...*/}
}
Alternatively, i could also include all the functions into a helper.
In a notification_helper.php file, i will include set_message(), get_message(), update_message()..
Where either way, it still can be reused. So this got me thinking about the decision making point about when exactly do we create a library and a helper particularly in CI.
In a normal (framework-less) php app, the choice is clear as there is no helper, you will just need to create a library in order to reuse codes. But here, in CI, I would like to understand the core developers seperation of libraries and helpers
Well the choice comes down to set of functions or class. The choice is almost the same as a instance class verses a static class.
If you have just a simply group of functions then you only need to make a group of functions. If these group of functions share a lot of data, then you need to make a class that has an instance to store this data in between the method (class function) calls.
Do you have many public or private properties to store relating to your notification messages?
If you use a class, you could set multiple messages through the system then get_messages() could return a private array of messages. That would make it perfect for being a library.
There is a question I ask myself when deciding this that I think will help you as well. The question is: Am I providing a feature to my framework or am I consolidating?
If you have a feature that you are adding to your framework, then you'll want to create a library for that. Form validation, for example, is a feature that you are adding to a framework. Even though you can do form validation without this library, you're creating a standard system for validation which is a feature.
However, there is also a form helper which helps you create the HTML of forms. The big difference from the form validation library is that the form helper isn't creating a new feature, its just a set of related functions that help you write the HTML of forms properly.
Hopefully this differentiation will help you as it has me.
First of all, you should be sure that you understand the difference between CI library and helper class. Helper class is anything that helps any pre-made thing such as array, string, uri, etc; they are there and PHP already provides functions for them but you still create a helper to add more functionality to them.
On the other hand, library can be anything like something you are creating for the first time, any solution which might not be necessarily already out there.
Once you understand this difference fully, taking decision must not be that difficult.
Helper contains a group of functions to help you do a particular task.
Available helpers in CI
Libraries usually contain non-CI specific functionality. Like an image library. Something which is portable between applications.
Available libraries in CI
Source link
If someone ask me what the way you follow when time comes to create Helpers or Libraries.
I think these differences:
Class : In a nutshell, a Class is a blueprint for an object. And an object encapsulates conceptually related State and Responsibility of something in your Application and usually offers an programming interface with which to interact with these. This fosters code reuse and improves maintainability.
Functions : A function is a piece of code which takes one more input in the form of parameter and does some processing and returns a value. You already have seen many functions like fopen() and fread() etc. They are built-in functions but PHP gives you option to create your own functions as well.
So go for Class i.e. libraries if any one point matches
global variable need to use in two or more functions or even one, I hate using Global keyword
default initialization as per each time call or load
some tasks are private to entity not publicly open, think of functions never have public modifiers why?
function to function dependencies i.e. tasks are separated but two or more tasks needs it. Think of validate_email check only for email sending script for to,cc,bcc,etc. all of these needs validate_email.
And Lastly not least all related tasks i.e. functions should be placed in single object or file, it's easier for reference and remembrance.
For Helpers : any point which not matches with libraries
Personally I use libraries for big things, say an FTP-library I built that is a lot faster than CodeIgniters shipped library. This is a class with a lot of methods that share data with each other.
I use helpers for smaller tasks that are not related to a lot of other functionality. Small functions like decorating strings might be an example. Or copying a directory recursively to another location.