Set the value of a global variable in a function

拟墨画扇 提交于 2020-01-26 03:59:05

问题


I'm currently working on an SAP Fiori app that consumes an OData service.

I created a method in my controller fonct that calculates a variable coming from my OData.

I want to capture this value and put it in a global variable every time the view is refreshed.

I created a global variable like this:

var boo1;
return Controller.extend("com.controller.Detail", {...});

and I passed boo1 as a parameter in my method fonct inside my onInit method but it is undefined.

Here's a snippet of my controller's code:

sap.ui.define([
    "com/util/Controller"
], function(Controller) {
    "use strict";

    var boo1;
    return Controller.extend("com.controller.Detail", {
        onInit: function() {
            this.fonct(boo1);
            alert(boo1);
        },          

        fonct: function(ovar) {
            var that = this;
            var oModel = that.getView().getModel();
            oModel.read("/alertSet", {
                success: function(data) {
                    var a = JSON.stringify(data);
                    var b = a.slice(332,-4);
                    ovar = b;
                }
            });
        }

    });
});

回答1:


You should declare the global variable at global scope (i.e., before sap.ui.define).




回答2:


I think that what you want to do is simplier that what you are doing. To save a global variable, get the Core object and set the variable as a new property of this object:

sap.ui.getCore().myGlobalVar = myCalculatedValue;

Then to use it in other view, get the property directly from the Core:

var mySavedVar = sap.ui.getCore().myGlobalVar

Then use the Router routeMatched event to handle your navigation and refresh the value.

Here a snippet: https://jsbin.com/bewigusopo/edit?html,output

    <!DOCTYPE html>
<html><head>
    <meta http-equiv='X-UA-Compatible' content='IE=edge' >
    <meta charset="UTF-8" >
    <title>test</title>

    <script id='sap-ui-bootstrap'
            src='https://sapui5.hana.ondemand.com/1.38.5/resources/sap-ui-core.js'
        data-sap-ui-theme='sap_bluecrystal'
        data-sap-ui-bindingSyntax="complex"></script>

    <script id="view1" type="sapui5/xmlview">
        <mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc">
            <core:ComponentContainer name='my.comp'/>
        </mvc:View>
    </script>

    <script id="home" type="sapui5/xmlview">
        <mvc:View xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"
            controllerName="my.controller1">
            <Page>
                <Input id="input" placeholder="Write a text to save it globally"/>
                <Button text="Navigate to other view" press="onNavigate"/>
            </Page>
        </mvc:View>
    </script>

    <script id="add" type="sapui5/xmlview">
        <mvc:View xmlns="sap.m" xmlns:f="sap.ui.layout.form" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"
            controllerName="my.controller2">
            <Page id="page" showNavButton="true" navButtonPress="onBack">
              <HBox class="sapUiLargeMarginBegin">
                 <Label text="The global variable is:" class="sapUiSmallMarginEnd sapUiSmallMarginTop"/>
                 <Input id="inputResult"/>
              </HBox>
            </Page>
        </mvc:View>
    </script>

    <script>
        // jQuery.sap.declare("my.comp.Component");
        sap.ui.define("my/comp/Component", ["sap/ui/core/UIComponent"], function(UIComponent) {
            return UIComponent.extend("my.comp.Component", {
                metadata : {
                    name : "GreatComponent",
                    version : "1.0",
                    includes : [],
                    dependencies : {
                        libs : ["sap.m"]
                    },
                    routing: {
                        config: {
                            routerClass: "sap.m.routing.Router",
                            viewType: "XML",
                            viewPath: "my",
                            controlId: "app",
                            transition: "slide",
                            controlAggregation: "pages"
                        },
                        routes: [
                            {
                                name: "home",
                                pattern: "",
                                target: "home"
                            },
                            {
                                name: "add",
                                pattern: "add",
                                target: "add"
                            }
                        ],
                        targets: {
                            home: {
                                viewName: "Home",
                                title: "home"
                            },
                            add: {
                                viewName: "Add",
                                title: "add"
                            }
                        }
                    }
                },
                init: function() {
                    sap.ui.core.UIComponent.prototype.init.apply(this, arguments);
                    var oRouter = this.getRouter();
                    var oViews = oRouter.getViews();
                    this.runAsOwner(function() {
                        var myHome = sap.ui.xmlview({viewContent:jQuery('#home').html()});
                        oViews.setView("my.Home", myHome);
                        var myAdd = sap.ui.xmlview({viewContent:jQuery('#add').html()});
                        oViews.setView("my.Add", myAdd);
                    });
                    oRouter.initialize();
                },
                createContent : function() {
                    var componentData = this.getComponentData();
                    return new sap.m.App("app", {
                    });
                }
            });
        });

        sap.ui.define("my/controller1", [
          "sap/ui/core/UIComponent"
        ],function(UIComponent) {
            return sap.ui.controller("my.controller1", {
                onInit: function() {
                    this.oRouter = UIComponent.getRouterFor(this.getView());
                },

                onNavigate: function() {
                    var sInputText = this.getView().byId("input").getValue();
                    sap.ui.getCore().myGlobalVar = sInputText;     
                    console.log(sap.ui.getCore().myGlobalVar)

                    this.oRouter.navTo("add");
                }
            });
        });

        sap.ui.define("my/controller2", [
          "sap/ui/core/UIComponent"
        ],function(UIComponent) {
            return sap.ui.controller("my.controller2", {
                onInit: function() {
                    this.oRouter = UIComponent.getRouterFor(this.getView());

                    this.oRouter.getRoute("add").attachPatternMatched(this._onObjectMatched, this);
                },

                _onObjectMatched: function(){
                    var sGlobalVariable = sap.ui.getCore().myGlobalVar;
                    console.log(sGlobalVariable);
                    this.getView().byId("inputResult").setValue(sGlobalVariable);
                },

                onBack: function(){
                    this.oRouter.navTo("home");
                }
            });
        });
        sap.ui.require(["my/comp/Component"], function(myComp) {
            // instantiate the View
            sap.ui.xmlview({viewContent:jQuery('#view1').html()}).placeAt('content');
        });
    </script>

</head>
<body class='sapUiBody'>
    <div id='content'></div>
</body>
</html>

Other possibility is to set a global model, which will simplyfy your binding very much. Just create it and set it into the Core

//To set it
var oGlobalModel = new sap.ui.model.json.JSONModel();
sap.ui.getCore().setModel(oGlobalModel, "myGlobalModelID");

//To get it
var oMyGlobalModel = sap.ui.getCore().getModel("myGlobalModelID");



回答3:


Please, avoid defining global variables (such as before sap.ui.define) especially if you are working on apps that are going to be placed into the Fiori Launchpad. This approach is considered harmful. This is also repeated in the documentation:

In control and class modules, you should not use global variables at all.(src)

We're using "use strict" purposely to disallow such practices.

Also, defining properties or adding models on sap.ui.getCore() is an anti-pattern for Fiori apps. Not only does this lead to the same flaws as defining global variables but models set on the core are not propagated to the views by default because components are meant to be used modularly. Therefore, defining such data to the corresponding component instead of the core is the way to go for Fiori apps.

==> FLP Best Practices


I created a global variable

var boo1;
return Controller.extend("com.controller.Detail", {...});

What you created though was not a global variable since boo1 was declared inside an anonymous function. Instead, boo1 was stored in a closure which allowed the prototype methods (onInit and fonc) to maintain the lexical environment within which boo1 was made accessible not only by the methods but also by other instances of com.controller.Detail. In terms of Java, we can say that boo1 is a private static variable. But it's not a global variable.

That being said..

I passed boo1 as a parameter in my method fonct inside my onInit method but it is undefined

The closure makes passing boo1 as an argument unnecessary (unless you want a hard copy of boo1 to maintain multiple states of it). The method fonct can access boo1 directly, even in the anonymous callbacks defined in fonct.

Now, you may be asking why boo1 was undefined. There are two reasons:

  1. boo1 was undefined before calling fonct. If boo1 were an object instead of undefined, then ovar would have been a reference to the boo1 object and the change to any ovar property would have took place in the boo1 object. But undefined is not an object. So ovar doesn't know what boo1 is at all. Note: The evaluation strategy of JS is "Call by object-sharing".
  2. alert(boo1) gets fired right after calling fonct. Unless oModel works synchronously (which I strongly recommend not to do so), the browser doesn't wait for the success callback to get fired in order to invoke alert(boo1) later. The alert is fired immediately, and then the success callback where boo1 should be manipulated.

Removing ovar and using boo1 instead updates boo1 properly in the success callback.

fonct: function(/*no ovar*/) {
    //...
    oModel.read("/alertSet", {
        success: function(data) {
            //...
            boo1 = /*new value*/;
            alert(boo1);
        }.bind(this)
    });
}


来源:https://stackoverflow.com/questions/43709170/set-the-value-of-a-global-variable-in-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!