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

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

本文关键字:and Phonegap Cor Web for JS App ng-href compatible Angular      更新时间:2023-10-20

我们有一个Web和Phonegap应用程序,它在Web中使用Angular HTML5模式,由于Cordova/Phonegaps的限制,移动应用程序使用HashBang模式。直到不久,我们才在所有的ng-href前面加上#!我们很喜欢移动和网络。Angular会在解析时自动将href属性中的hashbang URL转换为html5 URL。

我们更新到了Angular 1.5,注意到了奇怪的行为:Hashbang链接可以在整个页面重新加载时工作(例如打开一个新的选项卡),但当点击它们并在同一页面中打开它们时就不行了。Angular只会再次打开当前页面并附加哈希,而不进行处理

我搜索了变更日志,但没有在ng href或$location中找到任何与此问题有关的变更提示。我如何设计我的链接,使它们在phonegap和网络中工作?

我找到了一个解决方案,但我希望有更好的解决方案。我创建了一个指令,覆盖ng href并根据配置的平台替换链接。这样,在cordova中,所有链接都是hashbang链接,而在web上,所有链接均为普通链接。

在代码示例中,window.isPhonegapApp被设置为用于指示状态的配置值。将myApp替换为您的应用程序名称。

// 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;
});