Ionic1.x 小总结

一些小牢骚:

在这个前端框架非常丰富的时代,选择一个合适的框架来做产品或做项目是一个相对纠结的决定;毕竟这些作品都还在发展,很多人甚至还没来得及使用它们就已经不在或者淘汰了,甚至原创团队都不得不做很大的break change;用户在发展,需求在变化,前端这个新兴的产业很吸引人又很淘气;用java就会用到spring,这点已经毋庸置疑;而面对前段这么多的选择,似乎很难统一意见。


最近结束了一个小项目,今天做一个小总结:

大致需求

这些基本就是客户的基本诉求;

选择开发框架

app的结构就是:native + web;通常的hybrid就是native+web,之前工作中使用过cordova(那时候还是phonegap),它本身只是一个web和native交互的框架,没有ui,要么自己实现,要么使用一些开源产品:jqmobile,appframework,touch等等;都有尝试过,在android的体验很不好,直到后来出现了ionic,这是一个相对企业产品级的框架,做产品的体验还不错;考虑到cordova是主web,次native的模式,于是我们决定采用native + ionic - cordova 的模式。

ionic1.x的基本认识

我一直在强调是 ionic1.x ,因为 ionic2 和 ionic1 基本不兼容,甚至不是同一个产品。

我觉得好的一些地方
我觉得不好的一些地方

一些尝试

//java调用js
public class PreviewWebview extends WebView {
  //...
  
  //这个方法可以执行到 webview中 javascript 代码中的公开可访问的函数
  //比如 _mWebview.runJS("resetTimer();"); 可以执行js的 window.resetTimer() 函数
  public void runJS(String js){
    this.loadUrl("javascript:" + js);
  }
}

//js调用java
public class WebviewActivity extends BaseActivity implements IWebAppView, ICheckVersionView{
  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    //这行代码,可以将this作为 window.FPM 注入到 javascript 上下文中
    _mWebview.addJavascriptInterface(this, "FPM");
  }
  
  // 而所有带有 JavascriptInterface 这个注解的方法都会暴露给javascript,可以直接调用
  // 比如 window.FPM.jsLogout()就可以调用该方法
  @JavascriptInterface
  public void jsLogout(){
    // code here
  }
}

这里面有一个坑就是,通常我们认为 js 中的 alertconfrim 可以被正常执行,其实不是这样的,android中这些函数是不能正常执行的,需要我们自己去实现它,而cordova正是通过这个机制实现的native和web的交互,这里不再赘述。总之通常,还是不要在js中使用 alert 这些弹框来实现你的逻辑;会有意想不到的问题。

// 这是一个隐藏底部菜单栏的指令
app.directive('hideTabs', ['$rootScope', function($rootScope) {
  return {
    restrict:'AE',
    link:function(scope, element, attributes){
      scope.$on('$ionicView.beforeEnter', function (event, viewData) {
        viewData.enableBack = true;
        scope.$watch(attributes.hideTabs, function (value) {
          $rootScope.hideTabs = true;
        });
      });
      scope.$on('$ionicView.beforeLeave', function () {
        $rootScope.hideTabs = false;
      });
    }
  }
}])

一些小收获

function goBack(){
  //通过angular.element 来注入scope实现函数的访问
  var appElement = document.querySelector('#app');
  var $scope = angular.element(appElement).scope();
  $scope.goBack();
}
.config(['$ionicConfigProvider', '$sceDelegateProvider', function($ionicConfigProvider, $sceDelegateProvider){
  $ionicConfigProvider.platform.android.tabs.position('bottom');
}])
public class PreviewWebview extends WebView {
  private void init(){
    //为前端h5提供一些PC端的接口,如:启用js,file,cache,localstorage等等
    WebSettings settings = getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setDomStorageEnabled(true);
    settings.setAllowFileAccess(true);
    settings.setAllowUniversalAccessFromFileURLs(true);
    settings.setDefaultTextEncodingName("UTF-8");
    settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
    settings.setAppCacheEnabled(true);
    settings.setDatabaseEnabled(true);
    setWebViewClient(_mWebviewClient);
    setWebChromeClient(_mChromeClient);
  }
}

主要还是不断的实践和总结,还是可以在ionic这款产品上学到很多的;不过介于这些总结,后面会开始尝试用 React 来做产品。

生命不息,折腾不止