在函数中设置全局变量的值
Set the value of a global variable in a function
我目前正在开发一个使用 OData 服务的 SAP Fiori app。
我在我的控制器 fonct
中创建了一个方法来计算来自我的 OData 的变量。
我想在每次刷新视图时捕获这个值并把它放在一个全局变量中。
我创建了一个这样的全局变量:
var boo1;
return Controller.extend("com.controller.Detail", {...});
并且我在 onInit
方法中将 boo1
作为参数传递给方法 fonct
但它是 undefined
.
这是我的控制器代码片段:
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;
}
});
}
});
});
您应该在全局范围内声明全局变量(即在 sap.ui.define
之前)。
我认为你想做的比你正在做的更简单。
要保存全局变量,获取 Core 对象并将变量设置为该对象的新 属性:
sap.ui.getCore().myGlobalVar = myCalculatedValue;
然后在其他视图中使用它,直接从核心获取 属性:
var mySavedVar = sap.ui.getCore().myGlobalVar
然后使用 Router routeMatched 事件来处理您的导航并刷新值。
这里是一个片段: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>
另一种可能性是设置一个全局模型,这将大大简化您的绑定。只需创建它并将其设置到核心
//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");
请避免定义全局变量(例如sap.ui.define
之前),尤其是当您正在开发将要放入 Fiori Launchpad 的应用程序时。这种做法是considered harmful。文档中也重复了这一点:
In control and class modules, you should not use global variables at all.(src)
我们有意使用 "use strict"
来禁止此类做法。
此外,在 sap.ui.getCore()
上定义属性或添加模型是 Fiori 应用程序的反模式。这不仅会导致与定义全局变量相同的缺陷,还会导致在核心 默认情况下 上设置的模型,因为组件应该以模块化方式使用。因此,将此类数据定义到相应的 组件而不是核心 是 Fiori 应用程序的方法。
I created a global variable
var boo1;
return Controller.extend("com.controller.Detail", {...});
您创建的不是 全局变量,因为 boo1
是在匿名函数中声明的。相反,boo1
存储在 closure 中,它允许原型方法(onInit
和 fonc
)维护 boo1
可访问的词法环境仅通过方法,还通过 com.controller.Detail
的其他实例。在 Java 方面,我们可以说 boo1
是一个私有静态变量。但它不是全局变量。
话虽如此..
I passed boo1
as a parameter in my method fonct
inside my onInit
method but it is undefined
闭包使得不需要将 boo1
作为参数传递(除非您想要 boo1
的硬拷贝来维护它的多个状态)。方法 fonct
可以直接访问 boo1
,即使在 fonct
.
中定义的匿名回调中也是如此
现在,您可能会问为什么 boo1
是 undefined
。有两个原因:
boo1
在调用 fonct
之前是 undefined
。如果 boo1
是一个对象而不是未定义的,那么 ovar
将是对 boo1
对象的引用,并且对任何 ovar
属性 的更改都需要放置在 boo1
对象中。但是 undefined
不是对象。所以 ovar
根本不知道 boo1
是什么。 注意:JS的求值策略是“Call by object-sharing”。
alert(boo1)
在调用 fonct
后立即被解雇。除非 oModel
同步工作(我强烈建议 不要 这样做),浏览器不会等待成功回调被触发以调用 alert(boo1)
之后。立即触发警报,然后是 boo1
应该被操作的成功回调。
删除 ovar
并改用 boo1
在成功回调中正确更新 boo1
。
fonct: function(/*no ovar*/) {
//...
oModel.read("/alertSet", {
success: function(data) {
//...
boo1 = /*new value*/;
alert(boo1);
}.bind(this)
});
}
我目前正在开发一个使用 OData 服务的 SAP Fiori app。
我在我的控制器 fonct
中创建了一个方法来计算来自我的 OData 的变量。
我想在每次刷新视图时捕获这个值并把它放在一个全局变量中。
我创建了一个这样的全局变量:
var boo1;
return Controller.extend("com.controller.Detail", {...});
并且我在 onInit
方法中将 boo1
作为参数传递给方法 fonct
但它是 undefined
.
这是我的控制器代码片段:
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;
}
});
}
});
});
您应该在全局范围内声明全局变量(即在 sap.ui.define
之前)。
我认为你想做的比你正在做的更简单。 要保存全局变量,获取 Core 对象并将变量设置为该对象的新 属性:
sap.ui.getCore().myGlobalVar = myCalculatedValue;
然后在其他视图中使用它,直接从核心获取 属性:
var mySavedVar = sap.ui.getCore().myGlobalVar
然后使用 Router routeMatched 事件来处理您的导航并刷新值。
这里是一个片段: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>
另一种可能性是设置一个全局模型,这将大大简化您的绑定。只需创建它并将其设置到核心
//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");
请避免定义全局变量(例如sap.ui.define
之前),尤其是当您正在开发将要放入 Fiori Launchpad 的应用程序时。这种做法是considered harmful。文档中也重复了这一点:
In control and class modules, you should not use global variables at all.(src)
我们有意使用 "use strict"
来禁止此类做法。
此外,在 sap.ui.getCore()
上定义属性或添加模型是 Fiori 应用程序的反模式。这不仅会导致与定义全局变量相同的缺陷,还会导致在核心
I created a global variable
var boo1; return Controller.extend("com.controller.Detail", {...});
您创建的不是 全局变量,因为 boo1
是在匿名函数中声明的。相反,boo1
存储在 closure 中,它允许原型方法(onInit
和 fonc
)维护 boo1
可访问的词法环境仅通过方法,还通过 com.controller.Detail
的其他实例。在 Java 方面,我们可以说 boo1
是一个私有静态变量。但它不是全局变量。
话虽如此..
I passed
boo1
as a parameter in my methodfonct
inside myonInit
method but it isundefined
闭包使得不需要将 boo1
作为参数传递(除非您想要 boo1
的硬拷贝来维护它的多个状态)。方法 fonct
可以直接访问 boo1
,即使在 fonct
.
现在,您可能会问为什么 boo1
是 undefined
。有两个原因:
boo1
在调用fonct
之前是undefined
。如果boo1
是一个对象而不是未定义的,那么ovar
将是对boo1
对象的引用,并且对任何ovar
属性 的更改都需要放置在boo1
对象中。但是undefined
不是对象。所以ovar
根本不知道boo1
是什么。 注意:JS的求值策略是“Call by object-sharing”。alert(boo1)
在调用fonct
后立即被解雇。除非oModel
同步工作(我强烈建议 不要 这样做),浏览器不会等待成功回调被触发以调用alert(boo1)
之后。立即触发警报,然后是boo1
应该被操作的成功回调。
删除 ovar
并改用 boo1
在成功回调中正确更新 boo1
。
fonct: function(/*no ovar*/) {
//...
oModel.read("/alertSet", {
success: function(data) {
//...
boo1 = /*new value*/;
alert(boo1);
}.bind(this)
});
}