简体   繁体   中英

Angular JS App ng-href compatible for Web and Phonegap / Cordova

We have a Web and Phonegap App, that uses Angular HTML5 Mode in the Web, and, because of Cordova/Phonegaps limitations, HashBang Mode for the mobile Apps. Until shortly we just prefixed all our ng-hrefs with #! and we were good to go for mobile and web. Angular would automatically convert the hashbang urls in the href attributes to html5 urls when resolving.

We updated to Angular 1.5 and noticed weird behaviour: The Hashbang links would work on a full page reload (eg opening a new Tab) but not when clicking on them and opening them in the same page. Angular would just open the current page again and append the hash, without processing it.

I searched the changelog , but did not find any hints on changes in ng-href or $location concerning this issue. How could I design my links so they work in phonegap and the web?

I found a solution, but I hope there is a better one. I created a directive that overwrites ng-href and replaces the links according to the platform configured. This way, in cordova all links are hashbang links and on the web all links are normal links.

In the code sample, window.isPhonegapApp is set as configuration value to indicate the state. replace myApp with your app name.

// directive that replaces hashbangs according to app type
angular.module('myApp')
.directive('ngHref', function($interpolate) {
return {
    priority: 99, // it needs to run after the attributes are interpolated
    link: function(scope, element, attr) {
        var attrName = 'href',
            name = 'href';

        if (attrName === 'href' &&
            toString.call(element.prop('href')) === '[object SVGAnimatedString]') {
            name = 'xlinkHref';
            attr.$attr[name] = 'xlink:href';
        }

        var normalized = attr.$normalize('ng-href');
        attr.$observe(normalized, function(value) {
            if (!value) {
                if (attrName === 'href') {
                    attr.$set(name, null);
                }
                return;
            }


            if(window.isPhonegapApp) {
                if(!value.startsWith('#!')) {
                    value = '#!' + value;
                }
            } else {
                if(value.startsWith('#!')) {
                    value = value.replace("#!", '');
                }
            }
            attr.$set(name, value);
        });
    }
};
    // kick out the old ng-href directive and overwrite it with our directive
}).decorator('ngHrefDirective', function ngClickDecorator( $delegate) {

    var filteredDelegates =  _.filter($delegate, function($directive) {
        // replace with your app name
        return $directive.$$moduleName == 'myApp';
    });

    return filteredDelegates;
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM