问题
I am working on an Ionic app where users can post markdown content. In order to make this work, I am using the angular-marked library. In the app, I want all markdown links to be opened in the OS's default browser so I have done two things.
I have written an angular directive that forces links to open in the OS' browser using the ngCordova wrapper for cordova-plugin-inappbrowser.
I have set angular-marked's configuration to render all links using this directive.
The problem is that the links do not open in the system browser. They open in the current WebView. It might be that my directive is just bad or maybe directives aren't even the right thing to use in this case.
What am I doing wring in my code? How can I fix my issue to open links in the system browser?
My Directive.
.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');
});
}
};
}])
My Config
.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>';
}
});
}
])
回答1:
There are two problems with your code
1. the name of an angular directive should be in camelCase
, it will be converted to kebab-case
in HTML. This is very easy to fix, just change
.directive('fab-extLink', ['$cordovaInAppBrowser', function($cordovaInAppBrowser){
to
.directive('fabExtlink', ['$cordovaInAppBrowser', function($cordovaInAppBrowser){
2. in your case, there is <a fab-extlink>
in your HTML, but angular doesn't $compile
(instantiate) it.
This is a difficult one (if you don't want to monkey-patch angular-marked).
angular-marked
uses element.html(marked(text, scope.opts || null));
to set the inner HTML of the element, it skips angular's compiling process, so directives aren't initialized..
One workaround is to use a global function (not elegant I know):
Define it in app.run:
.run(function ($cordovaInAppBrowser) {
window.openInSystemBrowser=function(link){
$cordovaInAppBrowser.open(link, '_system');
};
and config angular-marked to use onclick, so that it works independent of angular.
markedProvider.setRenderer({
link: function (href, title, text) {
return '<a onclick="openInSystemBrowser(\'' + href + '\')"' + (title ? ' title="' + title + '"' : '') + '>' + text + '</a>';
}
});
The other way I can think of is to fork and patch angular-marked.
The monkey-patch solution:
- Open
angular-marked.js
replace
element.html(marked(text, scope.opts || null));
with
element.replaceWith($compile(marked(text, scope.opts || null))(scope));
update2
I checked the repo, the newest version of angular-marked (v1.2) supports an attribute called compile
, to do exactly that.
e.g.
<marked compile="true">
# Markdown [Google](http://www.google.com)
*It works!*
</marked>
So, in conclusion..
TLDR version
1. change
.directive('fab-extLink', ...
to
.directive('fabExtlink', ...
2. add attribute compile='true'
to <marked>
directive
回答2:
If you are looking for a easy way to open links in native browsers on mobile devices with marked can you just try setting this in your angular .config:
markedProvider.setRenderer({
link: function(href, title, text) {
return "<a href='" + href + "'" + (title ? " title='" + title + "'" : '') + " onclick='window.open("+href+", '_system')'" + " target='_system'>" + text + "</a>";
}
});
And then you would need to bind an onDeviceReady
function somewhere like this:
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
window.open = cordova.InAppBrowser.open;
}
来源:https://stackoverflow.com/questions/36948337/angular-marked-and-inappbrowser-opening-all-links-in-the-system-browser