IBM MobileFirst Adapter 如何与 Angular JS 集成?
How IBM MobileFirst Adapter integrate with Angular JS?
我正在使用 IBM MobileFirst + Ionic + AngularJS,创建一个按姓名搜索客户并将结果列在 table 中的程序。
假设我有一个适配器:
<wl:adapter name="customerAdapter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wl="http://www.ibm.com/mfp/integration"
xmlns:sql="http://www.ibm.com/mfp/integration/sql">
<displayName>customerAdapter</displayName>
<description>customerAdapter</description>
<connectivity>
<connectionPolicy xsi:type="sql:SQLConnectionPolicy">
<dataSourceDefinition>
<driverClass>oracle.jdbc.driver.OracleDriver</driverClass>
<url>jdbc:oracle:thin:@//10.128.2.155:1521/MyDB</url>
<user>admin</user>
<password>admin</password>
</dataSourceDefinition>
</connectionPolicy>
</connectivity>
<procedure name="searchCustomerByIC"/>
<procedure name="searchCustomerByNM"/>
<procedure name="searchCustomerByICandNM"/>
这是实现:(对于 searchCustomerByNM)
var statementSearchCustomerByNM= WL.Server.createSQLStatement("select CUST_NM,CUST_NIRC,CUST_GENDER from TB_CUSTOMER where CUST_NM like UPPER(?) ");
function searchCustomerByNM(customerName) {
return WL.Server.invokeSQLStatement({
preparedStatement : statementSearchCustomerByNM,
parameters : [new String("%" + customerName + "%")]
});
}
适配器运行良好。
这是我的 GUI 代码:
<ion-view view-title="Customer">
<ion-content>
<div id = "pageCustomer">
<div class="list">
<label class="item item-input">
<input type="text" placeholder="Customer Name" ng model="customerName">
</label>
<label class="item item-input">
<input type="text" placeholder="Customer IC" ng-model="customerIc">
</label>
<button class="button button-full button-positive" ng-click="customerSearch(customerName)">
Search Customer
</button>
</div>
<hr>
<table id="myTable" cellpadding="5" align="center" >
<thead>
<tr>
<th data-priority="2">Name</th>
<th data-priority="1">NIRC</th>
<th data-priority="persist">Gender</th>
<td></td>
</tr>
</thead>
<tr ng-repeat="x in customers">
<td>{{ x.name }}</td>
<td>{{ x.ic}}</td>
<td>{{ x.gender }}</td>
</tr>
</table>
</div>
</ion-content>
</ion-view>
这是我的服务:
app.service("customerSearchService",function()
{
this.searchByName = function(name){
var invokeData = {
adapter:"customerAdapter",
procedure:["searchCustomerByNM"],
parameters:[name]
};
var options = {
onSuccess:loadSQLQuerySuccess,
onFailure:loadSQLQueryFailure,
invocationContext:{'action':'Search Customer'}
};
WL.Client.invokeProcedure(invokeData,options);
function loadSQLQuerySuccess(result){
var customers = new Array();
var SJ = JSON.parse(JSON.stringify(result));
var length = SJ.invocationResult.resultSet.length;
for(var i=0;i<length;i++)
{
customers[i] = {name:SJ.invocationResult.resultSet[i].CUST_NM , ic:SJ.invocationResult.resultSet[i].CUST_NIRC , gender:SJ.invocationResult.resultSet[i].CUST_GENDER};
}
return customers;
}
function loadSQLQueryFailure(){
console.log("failureSend");
alert("failureSend");
var customers = new Array();
return customers;
}
}
});
这是我的控制器:
app.controller('CustomerCtrl', function($scope, customerSearchService,busyIndicator) {
$scope.getCustomers = function(customerName)
{
$scope.customers = [];
busyIndicator.show();
$scope.customers = customerSearchService.searchByName(customerName);
alert($scope.customers);
busyIndicator.hide();
};
$scope.customerSearch=function(customerName){
$scope.getCustomers(customerName);
}
})
我应该如何编写服务和控制器? (请提供我的代码)
我之前尝试过,但我的函数保留 return 空结果,因为结果是 return 在适配器获取所有数据之前编辑的。如何等待适配器获取所有数据?
提前致谢。
主要问题是您的 searchByName
没有 return 任何东西。
仔细观察,您会发现只有 return
语句在其他函数中。因此,您的函数调用将在没有 returning 任何内容的情况下结束。就像你说的,它会 return 甚至在调用完成之前。
您遇到的是 asynchronous
服务的典型流程。
我知道有两种方法可以解决这个问题:
- 承诺:
Promises 允许您 "wait" 以某种方式获得答案,就像您问的那样。
阅读一般的 Promises:http://www.html5rocks.com/en/tutorials/es6/promises/
阅读 AngularJS 中的 Promises:https://docs.angularjs.org/api/ng/service/$q
了解服务中的承诺:http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/
- AngularJS广播
广播允许您从一个地方(您的服务)发送消息并在另一个地方(您的控制器)接收它。所以你可以在完成后 ping 你的控制器:$on and $broadcast in angular
你能尝试在你的服务中使用 $q ( https://docs.angularjs.org/api/ng/service/$q )
app.service("customerSearchService",function($q) // Add $q
{
this.searchByName = function(name){
var deferred = $q.defer();
var invokeData = {
adapter:"customerAdapter",
procedure:"searchCustomerByNM", // Note this is not an array
parameters:[name]
};
var options = {
onSuccess:loadSQLQuerySuccess,
onFailure:loadSQLQueryFailure,
invocationContext:{'action':'Search Customer'}
};
WL.Client.invokeProcedure(invokeData,options);
function loadSQLQuerySuccess(result){
var customers = new Array();
var SJ = JSON.parse(JSON.stringify(result));
var length = SJ.invocationResult.resultSet.length;
for(var i=0;i<length;i++)
{
customers[i] = {name:SJ.invocationResult.resultSet[i].CUST_NM , ic:SJ.invocationResult.resultSet[i].CUST_NIRC , gender:SJ.invocationResult.resultSet[i].CUST_GENDER};
}
//return customers;
deferred.resolve(customers);
}
function loadSQLQueryFailure(){
console.log("failureSend");
alert("failureSend");
var customers = new Array();
//return customers;
deferred.reject(customers);
}
return deferred.promise;
}
});
我还可以推荐您阅读并关注 Raymond Camden 的博客。他发表了多篇关于 MFP 和 Ionic 的文章,包括适配器的使用。
我正在使用 IBM MobileFirst + Ionic + AngularJS,创建一个按姓名搜索客户并将结果列在 table 中的程序。
假设我有一个适配器:
<wl:adapter name="customerAdapter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wl="http://www.ibm.com/mfp/integration"
xmlns:sql="http://www.ibm.com/mfp/integration/sql">
<displayName>customerAdapter</displayName>
<description>customerAdapter</description>
<connectivity>
<connectionPolicy xsi:type="sql:SQLConnectionPolicy">
<dataSourceDefinition>
<driverClass>oracle.jdbc.driver.OracleDriver</driverClass>
<url>jdbc:oracle:thin:@//10.128.2.155:1521/MyDB</url>
<user>admin</user>
<password>admin</password>
</dataSourceDefinition>
</connectionPolicy>
</connectivity>
<procedure name="searchCustomerByIC"/>
<procedure name="searchCustomerByNM"/>
<procedure name="searchCustomerByICandNM"/>
这是实现:(对于 searchCustomerByNM)
var statementSearchCustomerByNM= WL.Server.createSQLStatement("select CUST_NM,CUST_NIRC,CUST_GENDER from TB_CUSTOMER where CUST_NM like UPPER(?) ");
function searchCustomerByNM(customerName) {
return WL.Server.invokeSQLStatement({
preparedStatement : statementSearchCustomerByNM,
parameters : [new String("%" + customerName + "%")]
});
}
适配器运行良好。
这是我的 GUI 代码:
<ion-view view-title="Customer">
<ion-content>
<div id = "pageCustomer">
<div class="list">
<label class="item item-input">
<input type="text" placeholder="Customer Name" ng model="customerName">
</label>
<label class="item item-input">
<input type="text" placeholder="Customer IC" ng-model="customerIc">
</label>
<button class="button button-full button-positive" ng-click="customerSearch(customerName)">
Search Customer
</button>
</div>
<hr>
<table id="myTable" cellpadding="5" align="center" >
<thead>
<tr>
<th data-priority="2">Name</th>
<th data-priority="1">NIRC</th>
<th data-priority="persist">Gender</th>
<td></td>
</tr>
</thead>
<tr ng-repeat="x in customers">
<td>{{ x.name }}</td>
<td>{{ x.ic}}</td>
<td>{{ x.gender }}</td>
</tr>
</table>
</div>
</ion-content>
</ion-view>
这是我的服务:
app.service("customerSearchService",function()
{
this.searchByName = function(name){
var invokeData = {
adapter:"customerAdapter",
procedure:["searchCustomerByNM"],
parameters:[name]
};
var options = {
onSuccess:loadSQLQuerySuccess,
onFailure:loadSQLQueryFailure,
invocationContext:{'action':'Search Customer'}
};
WL.Client.invokeProcedure(invokeData,options);
function loadSQLQuerySuccess(result){
var customers = new Array();
var SJ = JSON.parse(JSON.stringify(result));
var length = SJ.invocationResult.resultSet.length;
for(var i=0;i<length;i++)
{
customers[i] = {name:SJ.invocationResult.resultSet[i].CUST_NM , ic:SJ.invocationResult.resultSet[i].CUST_NIRC , gender:SJ.invocationResult.resultSet[i].CUST_GENDER};
}
return customers;
}
function loadSQLQueryFailure(){
console.log("failureSend");
alert("failureSend");
var customers = new Array();
return customers;
}
}
});
这是我的控制器:
app.controller('CustomerCtrl', function($scope, customerSearchService,busyIndicator) {
$scope.getCustomers = function(customerName)
{
$scope.customers = [];
busyIndicator.show();
$scope.customers = customerSearchService.searchByName(customerName);
alert($scope.customers);
busyIndicator.hide();
};
$scope.customerSearch=function(customerName){
$scope.getCustomers(customerName);
}
})
我应该如何编写服务和控制器? (请提供我的代码) 我之前尝试过,但我的函数保留 return 空结果,因为结果是 return 在适配器获取所有数据之前编辑的。如何等待适配器获取所有数据?
提前致谢。
主要问题是您的 searchByName
没有 return 任何东西。
仔细观察,您会发现只有 return
语句在其他函数中。因此,您的函数调用将在没有 returning 任何内容的情况下结束。就像你说的,它会 return 甚至在调用完成之前。
您遇到的是 asynchronous
服务的典型流程。
我知道有两种方法可以解决这个问题:
- 承诺: Promises 允许您 "wait" 以某种方式获得答案,就像您问的那样。
阅读一般的 Promises:http://www.html5rocks.com/en/tutorials/es6/promises/
阅读 AngularJS 中的 Promises:https://docs.angularjs.org/api/ng/service/$q
了解服务中的承诺:http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/
- AngularJS广播 广播允许您从一个地方(您的服务)发送消息并在另一个地方(您的控制器)接收它。所以你可以在完成后 ping 你的控制器:$on and $broadcast in angular
你能尝试在你的服务中使用 $q ( https://docs.angularjs.org/api/ng/service/$q )
app.service("customerSearchService",function($q) // Add $q
{
this.searchByName = function(name){
var deferred = $q.defer();
var invokeData = {
adapter:"customerAdapter",
procedure:"searchCustomerByNM", // Note this is not an array
parameters:[name]
};
var options = {
onSuccess:loadSQLQuerySuccess,
onFailure:loadSQLQueryFailure,
invocationContext:{'action':'Search Customer'}
};
WL.Client.invokeProcedure(invokeData,options);
function loadSQLQuerySuccess(result){
var customers = new Array();
var SJ = JSON.parse(JSON.stringify(result));
var length = SJ.invocationResult.resultSet.length;
for(var i=0;i<length;i++)
{
customers[i] = {name:SJ.invocationResult.resultSet[i].CUST_NM , ic:SJ.invocationResult.resultSet[i].CUST_NIRC , gender:SJ.invocationResult.resultSet[i].CUST_GENDER};
}
//return customers;
deferred.resolve(customers);
}
function loadSQLQueryFailure(){
console.log("failureSend");
alert("failureSend");
var customers = new Array();
//return customers;
deferred.reject(customers);
}
return deferred.promise;
}
});
我还可以推荐您阅读并关注 Raymond Camden 的博客。他发表了多篇关于 MFP 和 Ionic 的文章,包括适配器的使用。