I'm writing a SAPUI5 application that have a sap.m.Table loaded at runtime. I want to use a factory method defined inside the controller (is this the best way?). To do this, after the aquiring of the model, I have to bind my table's aggregation (items) to that model:
tableSeason.bindAggregation("items", {
path: "/results",
factory: this.tableFactory
});
Sadly this piece of code doesn't work, becouse the function tableFactory have inner calls to this.
The tableFactory's prototype is tableFactory: function(sId, oContext){...}.
I dont want to put the whole code inside the tableFactory function, can someone suggests a way to resolve this problem?
Thanks,
Gabriele
If you wanna attach the function to the factory:
this.tableFactory.bind(this)
If you want to the function be called immediately
this.tableFactory.call(this)
this.tableFactory.apply(this)
Related
I have to test some RequireJS JavaScript code and don't understand how to replace a special object. This is the code (simplified) of one function within a RequireJS Module:
changeView: function (view) {
function setView(view) {
this.currentView = view;
}
setView(view);
},
Now I want to test, if currentView is view.
But where is the currentView object saved?
I tried several things in my tests:
expect(view.currentView).toBe(...);
expect(view.changeView.currentView).toBe(...);
I also tried to save the inner function as an extra function in the module but I could not access this currentView property from within my test. How do I need to do that?
The answer is:
expect(window.currentView).toBe(...);
An object called via this in a nested function seems to be stored in the window object.
So I have done this AJAX request with angularJS:
http://jsfiddle.net/c0Lkja0h/1/
When I use link like for example $http.get('http://api.wunderground.com/api/KEY/forecast/geolookup/conditions/q/San_Francisco.json') (without '+ city +' in the link) it works great. But when I add that variable, add to ng-model="city" and hit submit, then it says
city is not defined
How can I make it take city name from that input and use it in my newAJAXreq function when I click "Find Weather" button ? Also it would be cool that default link would be with static link (when person first visited the site), and after that city is taken from input if user wants. THANKS!
There are a couple of things wrong with your approach.
Don't name your controller. It should be an anonymous function that take as parameters the modules you want to inject, such as .controller(function($http){ //do something }); or .controller(['$http',function($http){ //do something }]) to avoid losing reference to your variables when you minify your js files.
Inside your controller, define the function you want that takes as parameter the city, such as $scope.sendAjax = function(city){ //do something }. In your view you are gonna call this function with only the argument you need ng-submit="sendAjax(city)"
Avoid using scope. From the great book AngularJS:Up and Running, by Shyam Seshadri and Brad Green:
If you used AngularJS prior to 1.2, you might have expected the $scope variable to be injected into the controller, and the variables helloMsg and goodbyeMsg to be set on it. In AngularJS 1.2 and later, there is a new syntax, the controllerAs syntax, which allows us to define the variables on the controller instance using the this keyword, and refer to them through the controller from the HTML.
The advantage of this over the earlier syntax is that it makes it explicit in the HTML which variable or function is provided by which controller and which instance of the controller. So with a complicated, nested UI, you don’t need to play a game of “Where’s Waldo?” to find your variables in your codebase. It becomes immediately obvious be‐ cause the controller instance is present in the HTML.
The alternative is in your view use the controller as syntax: "ng-controller="WeatherController as weather", and then always refer to the alias when you need to access Weather Controller scope, such as ng-submit="weather.sendAjax()".
In your controller, you will assign the function to this, as in this.sendAjax = function(){ \\do something }. A good practice is to assign this to another variable, since this can get overriden. So in the first line of your controller you can do var self=this and refer to the controller as self from this point on, as in self.sendAjax = function(){ \\do something }
I am using marionette in my application. I am showing ItemView through regions like in the following.
var productInfoViewObj=new productInfoView.ProductInfoView({model:tagInformationModel.tagInformationModelObj});
exports.MyApp.bodyContainer.show(productInfoViewObj);
This is the code, I written inside view.
exports.ProductInfoView=Backbone.Marionette.ItemView.extend({
domInfo:{
mainTemplateId:"tagProductListTpl",
tableTemplateId:"taginfoViewTpl",
tableContentDiv:"taginfoViewDiv",
//tad Info
tagInfoTabId:"tagInfoBtn",
productInfoTabId:"productInfoBtn"
},
template:function(){
return commonFunctions.templateCompilation("tagProductListTpl","");
},
onRender:function(){
console.log(document.getElementById("productInfoBtn"));
}
});
I am passing templateId and data as arguments to commonFunctions.templateCompilation. It will compile and return compiled string. That compiled result passing to template.
As per my assumption, after completion of template, onRender function will trigger. What I mean before onRender, dom will available whatever we are templating using template.
But I am getting null inside onRender function.
I want a callback, it should trigger after template available in dom. so I can access elements whatever I templated using template.
I can do one thing, whatever I written inside onRender, I can setup time like in the following way.
onRender:function(){
setTimeout(function(){console.log(document.getElementById("productInfoBtn"));},1000);
}
If I set time, working fine but it's not correct way to implement.
can anyone help me.
Thanks.
It's resolved, I have to use onShow instead of onRender function. Now it's working fine.
I have a component which works fine using AJAX and mootools. Currently the view.raw.php only has one function in it which is display. I've been trying to create other functions within the component to use from AJAX but I can't make it work.
I thought that the ajax call is:
url: 'index.php?option=com_optical_database&view=gender&task=hello&format=raw',
with a public function within the component called hello:
public function hello(){
but it ignores this and goes to the display function every time. Is there a way of avoiding this?
Look at the place where the GET parameter task is used.
In Joomla there is usually a switch statement for this, and when you want to define a new task, you first need to add a new case in this switch.
I'm using JavascriptMVC and have a controller of the form
$.Controller.extend('AppName.Controllers.ControllerName',
{
onDocument: true
}
{
initControllerName: function() {
...
},
testFucntion1() {
alert('yeah!!');
}
});
and I'd like to be able to call the function testFunction1() from the page generated by my view.
I found this question which seems to be asking the same thing, but I wasn't able to figure it out with the answer provided there.
I've tried
$('#controllername').testFunction1();
$('#ppame_controllername').testFunction1();
$('#ppame_controllers.controllername').testFunction1();
without success.
Thanks for your help!!
Martin Owen's answer is accurate except I found app_name_controller_name confusing at first.
A real example would be:
if your controller is defined like
$.Controller.extend('Layout.Controllers.Page',
...
then use
$(document).layout_page("testFunction1");
Layout = app_name
Page = controller_name
You can call your function with:
$(document).app_name_controller_name("testFunction1");
If you want to pass arguments to your function specify them after the function name:
$(document).app_name_controller_name("testFunction1", "Hello World");
The onDocument: true in the static section of your controller definition means that it is automatically attached to the document element, so that is how you get an instance of it. If you want to bind it to something else remove onDocument: true and use something like:
$('#main').app_name_controller_name();
That will create an instance of your controller and attach it to the $('#main') element. That element is then available in the controller's methods via this.element.
I don't know your situtation but you shouldn't really need to call controller methods very often - the controller should bind to events that are triggered by DOM elements and published by models. JMVC makes it very easy to bind controller methods to events: Listening To Events