Access one controller inside another in SAPUI5 - javascript

I have a SAPUI5 master detail page application. So in master page controller I need to access an element which is defined in detail view. How can I do it?
jQuery.sap.require("util.Formatter");
jQuery.sap.require("util.Networkaccess");
sap.ui.controller("view.Sales.SalesOrder.SoMaster", {
myFunc: function() {
var iconTabBar = this.byId('itabBar');
iconTabBar.setSelectedItem(iconTabBar.getItems()[1]);
}
})
The above code will through error because the itabBar element is not there in master view, it's defined in detail view file.

i am not sure i exactly know what you are trying to do, controls have unique id's prefixed by the view, you could try
var iconTabBar = sap.ui.getCore().byId("vwDetails--itabBar")

Related

How to check if a backbone view is rendered?

I am trying to append a view to an item in Backbone with a following code:
var viewContainer = this.$el.find('.view-container'),
pageWrap = this.$el.nextAll();
FIX
if (viewContainer.empty()) {
this.myView= new ProductsView();
viewContainer.append(application.myView.render().$el),
console.log(myView);
}
I am appending this view to the viewContainer with a toggle function, however, every time I click on the button, myView is appended again and again to the viewContainer instead of of only once. How do I check if the view is already rendered inside it before appending it? Is there a !this.rendered() equivalent I can use?
I found this thread but it is not helping me in this instance.
UPDATE - FROM console.log(viewContainer)
[div.view-container.product-container.active, div#subjects_menu.view-container.product-container.hidden.active, prevObject: p.fn.p.init[1], context: undefined, selector: ".view-container"]
From the looks of it, you want to make sure ProductsView is not created if it already exists.
Simplest way to do this would be:
if(!this.myView) {
this.myView= new ProductsView();
viewContainer.append(application.myView.render().$el),
}
It is better to work with application state than querying DOM. When you remove product view, simply do this.myView = null afterwards.
The only time you'd want to query DOM to know if a view is rendered is probably when you have to integrate an isolated external application over which you have no control that doesn't trigger any event/provide callbacks etc while rendering.

Javascript object persistency in Meteor js

Supposed that I created a js object like this
Cart = function Cart(){
this.contents = new Array();
}
Cart.prototype = {
add : function(obj){
this.contents.push(obj);
}
}
and put it in the project lib folder so that this object can be used project-wide.
Is it possible to use this object persistently in the template backend (js file)? For example, I declared :
Template.pageA.rendered = function(){
var smallCart = new Cart();
}
Can I use it in the template event? For example:
Template.pageA.events = {
'click button#add' : function(event){
smallCart.add('newItem'); //Is this object as same as the one in rendered?
}
}
I have been doing stuff by using Sessions but when there are a lot of operations to be done, the events will be cluttered with business logics and calculations. I want to avoid this, thus I am thinking of putting the logics into Javascript object functions.
Will this approach work? Will the object stay persistent?
You can place that code inside a Meteor.startup, so the object will persist always.
Meteor.startup(function(){
Cart = function Cart(){
this.contents = new Array();
}
Cart.prototype = {
add : function(obj){
this.contents.push(obj);
}
}
})
Is this object as same as the one in rendered? yes
From my point of view, putting the class definition of your cart into the lib folder can be good. If it's client-side code only, you can store it into a cart.js file into your client folder.
This definition will be available on client.
Then you need to store an instance of your cart. Instanciate a cart into your template can be a good idea (you don't need it before that), but your need to store a reference into you client side application scope (usually into app.js at the root of your client folder for example)
client/cart.js
Cart = function() {}....
client/app.js
myCart = null;
Into your template, you can instantiate the cart
myCart = new Cart();
If you're using your only on one template, you can store the instance directly to the template into the controller logic. Attach it to the rendered of the template is a bit wired, because you usually handle template rendering logic.
This way, a cart is going to be created for every user which come on your site and called the template. If you have a multi page app using iron router, myCart will be available whatever the page as soon as you have already create it into your template.
Be aware, in this way, if the client "refresh" the page reloading the JavaScript code, you'll loose the current cart. You need to persist the cart on local storage in order to support the refresh. Not worth in all the case, but for a shopping cart, can be usefull
Putting the Cart code in lib is correct, it will be available everywhere.
As far as smallCart is concerned you have declared it inside a function so it isn't available to the other template function.
Declare it outside the two functions and it will be available to both.
var smallCart;
Template.pageA.rendered = function(){
smallCart = new Cart();
}
Template.pageA.events = {
'click button#add' : function(event){
smallCart.add('newItem'); //Is this object as same as the one in rendered?
}
}

Javascript Variables in MVC Partial Views

This might be quite simple but I am having difficulties with it. I have a view where I am setting a javascript variable, within that view I display a partial view using RenderPartial like so:
#{Html.RenderPartial("MyPartialView");}
I need access to a js variable set in my View, in my PartialView. Is this possible? I know there are several other ways to pass data using models but for my unique scenario it would be very helpful if I could do it this way as I am already passing a model so I can't do it that way.
Why wouldn't you pass your model into your partial view ?
anyway you can add your property to window object and use it in your partial view.
UPDATE:
What I meant was to open script tag in your view as follows :
<script>
window.test = "test value";
</script>
and use it in your partial view as follows :
<script>
alert( window.test);
</script>
BTW you can pass additional info to you partial view . Html.Partial accepts a third parameter which is viewData dictionary .
#Html.Partial("PartialViewName", yourModel, new ViewDataDictionary(){ {"AdditionalModel", value} })
and you can access it in your partial view by its name :
ViewData["AdditionalModel"]
sorry for the late response

Invoke ViewComponent using javascript

I have a web page with a couple of view components, when I click on these components I open a simple editor for it, see image below. If I edit the text and hit enter, I would like to rerender the view component and not the hole page. Is it possible to invoke a view component using javascript to get this behaviour?
With updates, you should now be able to do this with asp.net core. You can return a ViewComponent from an IActionResult, then just call it with jQuery:
[Route("text-editor")]
public IActionResult TextEditor()
{
return ViewComponent("TextEditorViewComponent");
}
Then this can be called from your View with something as simple as this:
function showTextEditor() {
// Find the div to put it in
var container = $("#text-editor-container");
$.get("text-editor", function (data) { container.html(data); });
}
If you need to pass parameters to the ViewComponent you can do so in the IActionResult (maybe they trickle through from the View to there, to the view component, etc).
This is not possible today but you could build a standard proxy for viewcomponents if you'd like though (similarly you could build a proxy to partial views). e.g. you a catchall attribute route on an action.

GeoJSON layer does not get recreated when rendered using EmberJS's 'link-to' helper

I am trying to render a LeafletJS map where the colours of the states in the map are dependent on a global parameter that is set in the appropriate Ember route. The setting of the parameter is not the issue but rather the (re)creation of the geoJson layer. When hitting the URL for the first time or when reloading the page the correct map is created, however when the page is rendered using Ember's 'link-to' helper, the map still holds the state colours of the previous page.
drawAll: function() {
var that = this;
Ember.$.ajax('/data/sa_provinces.json').then( function(data){
Frontend.globalPaths = data;
that.get('store').findAll('province').then(function(provinces) {
provinces.forEach(function(province) {
var provinceGeoJSON = window.L.geoJson( province.get('dataFromJSON'),
{ style: province.get('geoJSONStyle'),
province: province,
onEachFeature: province.get('onEachFeature') });
province.set('geo_json', provinceGeoJSON);
provinceGeoJSON.addTo(Frontend.map);
window.province = province;
});
});
});
}.property('drawAll')
This drawAll function is located within a Ember controller and is called from an Ember template. The functions dataFromJSON, geoJSONStyle and onEachFeature are all called the first time a page is called or when the page is refreshed but not when the page is rendered using the Ember's 'link-to' helper. Neither are they called when the URL is entered manually.
If anyone has any ideas or experience with LeafletJS and/or Ember I would really appreciate your help. Thanks in advance, Greg.
The first issue I notice is that drawAll is a computed property, not a function - you seem to be confusing computed properties and functions.
http://emberjs.com/guides/object-model/computed-properties/
Ember computed properties are more like normal attributes that observe other variables, and recompute when those variables change. The property() method after the function declaration changes it into a computed property and specifies which variables the property depends on. On the last line you're specifying that drawAll observes itself, which doesn't make much sense.
You can't call functions from handlebars templates - you can only access properties. So you can access a property, with the side effect of causing that property's function to be called.
If you want just a function that is called as soon as the template loads, you can implement the didInsertElement function on that templates corresponding view, and the contents of the didInsertElement function will run when the template loads.
If you want a property that recomputes based on some conditions changing, you should change the last line to specify which conditions it is observing.
I can't be sure without more info about the template and controller you're using, but for your current use case it looks like you just want a function that runs whenever the template is inserted, so changing the drawAll to an actual function (by removing the .property('drawAll)) and calling it from didInsertElement of the corresponding view will rerun it every time the controller is inserted. Like:
didInsertElement: function() {
this.drawAll()
}
(You need to have created a view that corresponds to the controller in this context)

Categories

Resources