从Xamarin Forms中的AngularJs脚本调用C#函数PCL通用Windows应用程序
我正在开发跨平台的xamarin表单应用程序。我创建了一个便携式跨平台应用程序。其中我试图在webview中打开本地html页面。对于从angularjs调用c#函数,我已经实现了混合web视图概念。从Xamarin Forms中的AngularJs脚本调用C#函数PCL通用Windows应用程序
我angularjs功能
$scope.SyncServerJobs = function() {
//$scope.loadActList();
window.CommInterface.syncServerJobs("");
}
在我万能的Windows项目
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Windows.UI.Xaml.Controls.WebView>
{
public CommInterface communicator = new CommInterface();
const string JavaScriptFunction = "function invokeCSharpAction(data){window.external.notify(data);}";
const string SyncServerJobs = "function syncServerJobs(data){window.external.notify(data);}";
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var webView = new WebView();
webView.Settings.IsJavaScriptEnabled = true;
SetNativeControl(webView);
}
if (e.OldElement != null)
{
Control.NavigationStarting -= OnWebViewNavigationStarted;
Control.NavigationCompleted -= OnWebViewNavigationCompleted;
Control.ScriptNotify -= OnWebViewScriptNotify;
}
if (e.NewElement != null)
{
Control.NavigationStarting += OnWebViewNavigationStarted;
Control.NavigationCompleted += OnWebViewNavigationCompleted;
Control.ScriptNotify += OnWebViewScriptNotify;
Control.Source = new Uri(string.Format("ms-appx-web:///Content//{0}", Element.Uri));
}
}
private void OnWebViewNavigationStarted(WebView sender, WebViewNavigationStartingEventArgs args)
{
if (Control != null && Element != null)
{
communicator = new CommInterface();
Control.AddWebAllowedObject("CommInterface", communicator);
}
}
async void OnWebViewNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
if (args.IsSuccess)
{
// Inject JS script
await Control.InvokeScriptAsync("eval", new[] { JavaScriptFunction });
await Control.InvokeScriptAsync("eval", new[] { SyncServerJobs });
}
}
void OnWebViewScriptNotify(object sender, NotifyEventArgs e)
{
Element.InvokeAction(e.Value);
}
}
我commInterface类
[AllowForWeb]
public sealed class CommInterface
{
readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer;
public CommInterface()
{
}
public void syncServerJobs(string data)
{
HybridWebViewRenderer hybridRenderer;
if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
{
hybridRenderer.Element.SyncServerJobs(data);
}
}
}
像在Android的项目我使用CommInterface类与数据库进行通信便携式库中的类。但在我的通用Windows项目中,我无法与Csharp函数进行通信以执行CSharp CRUD函数。所以请看看我的问题一次,并帮助我从脚本调用CSharp函数。任何帮助将非常感谢你。
我无法与Csharp函数进行通信以进行CSharp CRUD函数。所以请看看我的问题一次,并帮助我从脚本调用CSharp函数。
在webView导航完成后,您已注入JS
脚本。换句话说await Control.InvokeScriptAsync("eval", new[] { JavaScriptFunction });
是在JS
范围内声明的。
Web查看内容中的脚本可以使用带有字符串参数的window.external.notify将信息发送回您的应用。要接收这些消息,请处理ScriptNotify
事件。
所以当你在JS
范围内执行JavaScriptFunction
时,会触发ScriptNotify
事件,如下面的代码。
<button type="button" onclick="javascript:invokeCSCode($('#name').val());">Invoke C# Code</button>
<br/>
<p id="result">Result:</p>
<script type="text/javascript">
function log(str)
{
$('#result').text($('#result').text() + " " + str);
}
function invokeCSCode(data) {
try {
log("Sending Data:" + data);
invokeCSharpAction(data);
}
catch (err){
log(err);
}
}
我发现你已经处理了ScriptNotify
事件由excuted Element.InvokeAction(e.Value);
因此,我推断你对混合Web视图宣布InvokeAction
。
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string data)
{
if (action == null || data == null)
{
return;
}
action.Invoke(data);
}
然后,您可以在回调函数中处理CSharp CRUD函数,如下面的代码。
smbridwebview.RegisterAction(data => {
// process CSharp CRUD functions
});