Angular Marked和Inappbrowser打开系统浏览器中的所有链接

时间:2016-04-29 22:21:13

标签: javascript cordova angularjs-directive inappbrowser

我正在开发一个Ionic应用程序,用户可以在其中发布降价内容。为了完成这项工作,我正在使用angular-marked库。在应用程序中,我希望所有降价链接都可以在操作系统的默认浏览器中打开,所以我做了两件事。

  1. 我写了一个角度指令,强制在操作系统中打开链接。浏览器使用ngCordova包装器为cordova-plugin-inappbrowser。

  2. 我已设置角度标记的配置,以使用此指令呈现所有链接。

  3. 问题是链接无法在系统浏览器中打开。它们在当前的WebView中打开。可能是我的指示很糟糕,或者指令在这种情况下甚至不是正确的用法。

    我在代码中做了什么?如何解决我在系统浏览器中打开链接的问题?

    我的指示。

      .directive('fab-extLink', ['$cordovaInAppBrowser', function($cordovaInAppBrowser){
    
                return {
                    restrict: 'A',
                    link: function(scope, elem, attrs) {
                        elem.bind('click', function(e) {
                            // Stop the link from opening.
                            e.preventDefault();
    
                            // Open the link with the operating system browser.
                            $cordovaInAppBrowser.open(attrs.href, '_system');
                        });
                    }
                };
        }])
    

    我的配置

    .config( [
          '$compileProvider',
          'markedProvider',
          function( $compileProvider, markedProvider)
          {
            $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
    
            // When markdown is rendered use the external link directive.
            markedProvider.setRenderer({
              link: function(href, title, text) {
                return '<a fab-extLink href="' + href + '"' + (title ? ' title="' + title + '"' : '') + '>' + text + '</a>';
              }
            });
          }
        ])
    

2 个答案:

答案 0 :(得分:3)

您的代码存在两个问题

1。 angular指令的名称应该在camelCase中,它将在HTML中转换为kebab-case。这很容易解决,只需更改

 .directive('fab-extLink', ['$cordovaInAppBrowser', function($cordovaInAppBrowser){

 .directive('fabExtlink', ['$cordovaInAppBrowser', function($cordovaInAppBrowser){

2。在您的情况下,HTML中有<a fab-extlink>,但angular不会$compile(实例化)它。

这是一个很难的(如果你不想用角度标记的猴子补丁)。

angular-marked使用element.html(marked(text, scope.opts || null));来设置元素的内部HTML,它会跳过angular的编译过程,因此指令不会被初始化。

一种解决方法是使用全局函数(我不知道):

在app.run中定义:

.run(function ($cordovaInAppBrowser) {
  window.openInSystemBrowser=function(link){
     $cordovaInAppBrowser.open(link, '_system');
  };

并配置角度标记以使用onclick,以便它独立于角度工作。

markedProvider.setRenderer({
        link: function (href, title, text) {
          return '<a onclick="openInSystemBrowser(\'' + href + '\')"' + (title ? ' title="' + title + '"' : '') + '>' + text + '</a>';
        }
      });

我能想到的另一种方法是分叉和修补角度标记。

猴子补丁解决方案:

  1. 打开angular-marked.js
  2. 替换

    element.html(marked(text, scope.opts || null));
    

    element.replaceWith($compile(marked(text, scope.opts || null))(scope));
    
  3. UPDATE2

    我检查了回购,最新版本的角度标记(v1.2)支持一个名为compile的属性,就是这样做。

    e.g。

    <marked compile="true">
              # Markdown [Google](http://www.google.com)
              *It works!*
    </marked>
    

    所以,最后......

    TLDR版本

    1。变化

     .directive('fab-extLink', ...
    

     .directive('fabExtlink', ...
    

    2。将属性compile='true'添加到<marked>指令

答案 1 :(得分:1)

如果您正在寻找一种在带有标记的移动设备上在原生浏览器中打开链接的简便方法,您只需尝试在角度.config中设置此内容:

public class UsersArrayList {
    public ArrayList<User> usersList;

    private UsersArrayList() {
        usersList = new ArrayList<User>();
    }

    public ArrayList<User> getUsersList() {
        return usersList;
    }    

    private static UsersArrayList instance;

    public static UsersArrayList getInstance() {
        if (instance == null) instance = new UsersArrayList();
        return instance;
    }
}

然后你需要在这样的地方绑定一个markedProvider.setRenderer({ link: function(href, title, text) { return "<a href='" + href + "'" + (title ? " title='" + title + "'" : '') + " onclick='window.open("+href+", '_system')'" + " target='_system'>" + text + "</a>"; } }); 函数:

onDeviceReady