I am learning backbone.js. I found the following code from backbone.js documentation.
//cretaing class name as Sidebar with extends Backbone.Model class
var Sidebar = Backbone.Model.extend({
promptColor:function() {
var cssColor = prompt("Please enter a CSS color:");
this.set({color1: cssColor});
}
});
//cretaing object for Sidebar class
var sidebarObject = new Sidebar();
//following statement not understand
sidebarObject.on("change:color1", function(model, color23) {
$('#body1').css({background: color23})
});
What I understand :
whenever attribute color1 will change automatically model('Slidebar') triggers sidebarObject.on().
What I didn't understand :
we are passing 2 arguments names are model,color23 to second argument of the sidebarObject.on(). I didn't understand anything about that arguments.
2.As per my understanding model is Sidebar in my example.Is it right.
can anyone help me.
Thanks.
Yes, your second assumption is correct, in the above example Sidebar is the Model.
There are 2 parameters being passed to the callback function:
the model on which the event initially occurred
the value being passed alongside with the event
Note that the sidebarObject listens only to 'color' change events. Such event is generated when you change that particular attribute of the model:
this.set({color1: cssColor});
Now, if you change the listener to:
sidebarObject.on("change:taste", function(model, color23) {
$('#body1').css({background: color23})
});
it won't be fire anymore when this.set({color: cssColor}); is called, because it listens to 'taste' change:
this.set({taste: 'good'});
I've separated the above example into a fiddle so you can play with it: http://jsfiddle.net/CtzsR/1/
If you are new to this whole thing http://backbonetutorials.com/what-is-a-model/ is a site worth looking at.
I hope now it's clearer.
Related
I have an existing Quick Action button on an object, which I would like to display as a button for Community Users
I have tried implementing lightning:quickActionAPI in a Lightning Component that I created, then added the component to the record detail page in Community Builder. I have changed the actual names of objects and fields with general names
<lightning:quickActionAPI aura:id="quickActionAPI" />
<lightning:button label="Update" onclick="{!c.updateRequestStatus }" />
updateRequestStatus : function(component, event, helper) {
//debugger;
var actionAPI = component.find("quickActionAPI");
var fields = {fieldApiName: {value:"Closed"}};
var args = {actionName: "objectApiName.quickActionName", entityName: "objectApiName", targetFields: fields};
actionAPI.setActionFieldValues(args).then(function(){
actionAPI.invokeAction(args);
}).catch(function(e){
console.error(e.errors);
});
}
Expected result: when clicking on the button in the community, the quick action will be called and a window will open
Actual result: clicking on the button executes the JS method but nothing happens
I'm currently seeing the same thing in my Community. The documentation says lightning:quickActionAPI is only available in Lightning Experience, and makes no references to Communities. I don't think it's supported, yet. Though it is confusing that the actionAPI object will instantiate just fine in a Community context but its promises never complete.
I am new to Backbone and am wondering something.
I've seen some tutorial where the user uses this code to explain an event.
var ImageModel = Backbone.Model.extend({ initialize: function(){
this.on('change',this.someChange,this); //when some property in this object has changed, run this.someChange() function },
defaults : { title : 'untitled',
description : 'no description available',
owner : 'anonymous',
date : 'no date supplied' },
someChange: function(model,options){ alert(‘something has changed’);
}
});
var photo = new ImageModel({title:’awesome image’}); //create new instance
photo.set(‘title’,’really awesome indeed’); //change the title attribute, this will trigger ‘change’ event
photo.set({title:’well i agree’},{agree: ‘yep’}); //alternative way to change model attribute with optional option passed, this will also trigger change event. </p>
And In some other examples I've seen people usings triggers to activate the event.
Eg
`var object = {};
_.extend(object, Backbone.Events); object.on("alert", function(msg) {
alert("Triggered " + msg); });
object.trigger("alert", "an event");
My questions is how do the first example use the event 'change' when it doesn't get trigged in anyway. It doesn't use 'change' anywhere in the code. I know that it uses the function someChange but how does it now to "activate" when the event isn't trigged or "used" in the code.
If you're not understanding the question I am sorry. Not sure how to explain the problem.
I think you need to spend a little time reading the Backbone documentation (shouldn't take you more than 1 hour). There is a list of predefined events you will be using a lot when writing Backbone applications: "change", "reset", and so on.
http://backbonejs.org/#Events-catalog
Regarding your particular example, Backbone.Events is the component used inside Backbone to provide any object/class with event emitting functionality. Backbone.Model of course includes Backbone.Events.
Your first snippet shows how to listen to a Backbone.Model change event to do something, while the second mixes the Backbone.Events into a JS object to be able to trigger from it.
That's the beauty of Backbone, the same methods (on, off, listenTo) are used in Models, Views, Collections, because they all inherit Backbone.Events. Once you grasp it, it's all rock and roll. :)
I was trying to change _onFormReset method in YUI (or Alloy UI) - I think it is common JavaScript (OOP) thing, but I am a noob in JS OOP and YUI (been using some JQuery till now) - how can I change functionality of method (keeping other methods as they are)?
for example;
Currently method looks like:
_onFormReset: function(event) {
var instance = this;
instance.resetAllFields();
},
(src: http://alloyui.com/api/files/alloy-ui_src_aui-form-validator_js_aui-form-validator.js.html#l1192)
But I want it to be like:
_onFormReset: function(event) {
var instance = this;
instance.resetAllFields();
/* PSEUDO:
**a.) action is logged (ajax call to DB)
b.) all fields in form are reset (default behaviour) + form get's a new anti CSFR UID via ajax
c.) notification is shown (like that message in my example but let's say: Form reseted!)
d.) (Submit button reappears)**
...
*/
},
I tried something like:
/* trying to hijack thingZ */
var FormReset = Y.Component.create({
// component name
NAME : 'form-validator-reset',
EXTENDS : Y.Base,
// Base component's method which extends
prototype : {
_onFormReset: function(event) {
var instance = this;
instance.resetAllFields();
Y.one("#submitit").setHTML("<h4>Thanks, form submitted ok</h4>");
}
}
});
But with no success.
I looked at documentation and wasn't able to find a way, also it seems like I am missing OOP Javascript basics :(
Can somebody help me "catch the fish" :)
Trying to learn good (OOP) JavaScript for a long time, reading a lot online, but best way for me is learning by coding and now I am really stuck...
So my wish is to have something that I can use in all my forms for when reset button is clicked (in same way I would also change Submit) - OOP method - attached to default reset function, upgrading it in "my" way.
It looks like you're trying to tackle this the wrong way. Unless you're just doing this as an exercise in overriding a method you really shouldn't do that if all you're trying to do is print out a thank you.
Also if you're looking to thank the user for submitting you should be trying to do that when the user submits the form, not when the form is reset. To do this you'd subscribe a function to the 'submit' event of the form.
A.one("#my_form").on("submit", function() {
Y.one("#submitit").setHTML("<h4>Thanks, form submitted ok</h4>");
});
Ok, after rethinking it, I suppose preventDefault is ok for me (I will try to learn OOP JS with other cases :)).
This is (a n00by) solution:
add #resetit to reset button
add code:
var ressetterr = Y.one("#resetit");
Y.one(ressetterr).on("click", function(e){
console.log("resetit");
e.preventDefault();
});
I'm trying to register my onClick listener to dijit Button placed as in-cell widget withing GridX. I've done the following, basing on example test_grid_cellWidget:
{ field: "save", name:"Save",
widgetsInCell: true,
navigable: true,
decorator: function(){
//Generate cell widget template string
return '<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="btn">Save</button>'
},
setCellValue: function(data){
//"this" is the cell widget
this.btn.set("label", "Speichern")
this.btn.connect("onClick", function(){
alert('clicked')
})
}
},
setCellValue is executed successfully, and the label is changed. However, the onClick listener is not registered and is not called, when I click on button. When I use the syntax data-dojo-props="onClick:function" it works, but it requires declaring listener function as global, which is something I'd like to avoid.
Anyway, I have the Button object, and I'm executing the code found in dijit documents, so it should be working. But why nothing is registered in that context?
I've found the answer in GridX wiki: https://github.com/oria/gridx/wiki/How-to-show-widgets-in-gridx-cells%3F
You need to use the field cellWidget.btn._cnnt:
setCellValue: function(gridData, storeData, cellWidget){
this.btn.set("label", "Speichern")
if(cellWidget.btn._cnnt){
// Remove previously connected events to avoid memory leak.
cellWidget.btn._cnnt.remove();
}
cellWidget.btn._cnnt = dojo.connect(cellWidget.btn, 'onClick', lang.hitch(cellWidget.cell, function(){
rowSaveClick(this.row)
}));
},
I don't know what dojo version you use, but as you use data-dojo-type, I suppose it's 1.7+.
First, I would recommend to drop the dot notation of module names and start using the AMD mid syntax instead (i.e.: drop "dijit.form.Button" for "dijit/form/Button", as the dot notation will be dropped in dojo 2.0).
Then, the recommended way of connecting events to widgets is to :
either define the event as a function (like widget.onClick = function(evt){...})
or use the "on" method of the widget (like widget.on("click", function(evt){...}))
I prefer to use the second form, as it's more consistent with dojo/on. It consists of using the event name without the "on", and put everything in lowercase. For example, if your widget had an extension point named "onMouseRightClick", you could use it as widget.on("mouserightclick", ...)
Your example would then become :
{ field: "save", name:"Save",
widgetsInCell: true,
navigable: true,
decorator: function(){
//Generate cell widget template string
return '<button data-dojo-type="dijit/form/Button" data-dojo-attach-point="btn">Save</button>'
},
setCellValue: function(data){
//"this" is the cell widget
this.btn.set("label", "Speichern")
this.btn.on("click", function(){
alert('clicked')
});
}
},
Note : untested code. I'm just guessing what the problem might be. Let me know if there is still an issue...
I've found that using getCellWidgetConnects works quite well (see docs).
But the docs aren't exactly clear, so it wasn't working for me at first. If you are connecting to a DomNode, the pass 'click' as the event in the connections array. If you are connecting to a Dijit widget, then pass 'onClick'.
Ember.LinkView, the the view class behind the handlebars {{linkTo}} helper is now public in Ember 1.0 RC2. I want to extend it so I can create a custom view without having an extra nested tag for linkTo.
For example:
App.MyLinkView = Ember.LinkView.extend({
namedRoute: 'another'
});
then
{{#view App.MyLinkView}}LinkView to another route{{/view}}
Looked through the source a bit without much luck, as it constantly throws an error.
Here's a jsfiddle with the standard {{linkTo}} working, and the LinkView attempt commented out so it doesn't throw an error.
http://jsfiddle.net/HgmEy/1/
Edit:
Here is a more realistic example of why you would want to do this:
http://jsfiddle.net/HgmEy/3/
The desired functionality is working here using a regular view, however using a LinkView would be preferred to avoid the extra dom element.
LinkView is intended to be created via a helper, which passes (and provides default values for) some options.
Your error occurs when trying to determine whether your custom class is active or not. You'll need to do one of the following
pass or supply the expected default options when using your App.MyLinkView
override the active function and implement what you need
just pass options to {{linkTo}} for the behavior you want
reopen Ember.LinkView to provide the app-wide behavior you'd want
I needed to do this to override Ember.LinkView's call to transitionTo in order to come up with a solution for jQuery animations between transitions. It seems to me that there are a couple of viable ways to override LinkView. The second one I succeeded with is Trek's last option, and is simpler. This is method #2:
Method #2
{{#linkTo 'items' this eventName="myEvent"}} Link to {{title}} {{/linkTo}}
Now rewrite the app-wide LinkView:
Ember.LinkView.reopen({
// this handler is still called on click, but
// if we specify eventName in our template,
// we can call that handler only when we need to,
// or not at all
click: function (e) {
var evtName = this.get('eventName');
// transitionTo was already invoked by
// this._invoke() if evtName was `click`
if (evtName === 'click') return;
e.preventDefault();
// do some stuff here
var args = [].slice.call(arguments);
this.trigger.apply(this, [evtName].concat(args));
}
});
Method #1
The first method I came up with was to extend Ember.LinkView and create a custom Handlebars helper. The Ember source was really handy here for reading, but I had to override a private method, so I don't think this is really ideal. Here's the implementation. Keep in mind I was trying to control when the View triggered a transitionTo:
{{#appLinkTo 'items' this}} Link to {{title}} {{/appLinkTo}}
Now code it up!
App.LinkView = Ember.LinkView.extend({
// always called after this.invoke(),
// which calls transitionTo
click: function (e) {
e.preventDefault();
},
// already bound to the click event by this.init().
// our click handler above always gets called after this one
_invoke: function (event) {
// we need to simulate the old _invoke if we
// want to override its call to transitionTo
//
// https://github.com/emberjs/ember.js/blob/v1.0.0/packages/ember-routing/lib/helpers/link_to.js#L297
var isSimpleClick = Ember.ViewUtils.isSimpleClick;
if (!isSimpleClick(event)) { return true; }
event.preventDefault();
if (this.bubbles === false) { event.stopPropagation(); }
if (this.get('_isDisabled')) { return false; }
if (this.get('loading')) {
Ember.Logger.warn("This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid.");
return false;
}
// now we can start messing around
var routeArgs = this.get('routeArgs');
// routeArgs seems to have format ['routeName', models for dynamic segments]
this.set('routeArgs', ['group', routeArgs[1]]);
// if we use:
this.get('controller').send('someAction', routeArgs);
// the controller can do in its `someAction` handler:
// `this.transitionToRoute.apply(this, routeArgs);`
}
});
// besides the naming, this is verbatim from the end of:
// https://github.com/emberjs/ember.js/blob/v1.0.0/packages/ember-routing/lib/helpers/link_to.js
Ember.Handlebars.registerHelper('app-link-to', function(name) {
var options = [].slice.call(arguments, -1)[0],
params = [].slice.call(arguments, 0, -1),
hash = options.hash;
hash.disabledBinding = hash.disabledWhen;
hash.parameters = {
context: this,
options: options,
params: params
};
return Ember.Handlebars.helpers.view.call(this, App.LinkView, options);
});
Ember.Handlebars.registerHelper('appLinkTo', Ember.Handlebars.helpers['app-link-to']);
Method #3
If you want the best of both, you could combine both methods and extend Ember.LinkView, create a custom Handlebars helper, and use custom event names to signify which actions you want to take. That way, overriding Ember.LinkView, and overwriting _invoke aren't necessary.
Good luck!