将 Angular UI-Router 与 Phonegap 一起使用

Posted

技术标签:

【中文标题】将 Angular UI-Router 与 Phonegap 一起使用【英文标题】:Using Angular UI-Router with Phonegap 【发布时间】:2014-03-17 10:11:56 【问题描述】:

我目前有一个使用 Angular 构建的项目,我将其部署到 Phonegap Build 服务以创建 iosandroid 发行版。最初,我使用的是 Angular 的内置路由服务。然而,嵌套多个视图的需要促进了我采用Angular UI-Router。我已经构建了一个简单的路由系统,可以在通过 Web 浏览器进行本地测试并使用 Ripple Emulator 时工作。

index.html如下:

<html lang="en" ng-app="myApp">


<head>
    <meta charset="utf-8" />
    <meta name="format-detection" content="telephone=yes" />
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, target-densitydpi=medium-dpi, user-scalable=0" />


    <!-- Styles -->

    <link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.css" />
    <link rel="stylesheet" type="text/css" href="css/photo-slider.css" />
    <link rel="stylesheet" type="text/css" href="css/spin.css" />
    <title>App Title</title>









</head>
<body>
    <div class="loader" id='ajax-loader'>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>



    <!-- View Container for the Header -->
    <div ui-view="header"></div>
    <!-- View Container for the Content -->
    <div ui-view="content"></div>




    <!-- Angular Libraries -->
    <script src="lib/angular.js"></script>
    <script src="lib/angular-resource.js"></script>
    <script src="lib/angular-route.js"></script>
    <script src="lib/angular-touch.js"></script>
    <!-- UI Router -->
    <script src="lib/angular-ui-router.js"></script>
    <!-- Bootstrap Angular Directives -->
    <script src='js/ui-bootstrap-tpls-0.10.0.js'></script>
    <!-- Peristence js -->
    <script src="lib/persistence.js"></script>
    <script src="lib/persistence.store.sql.js"></script>
    <script src="lib/persistence.store.websql.js"></script>
    <script src="lib/persistence.store.memory.js"></script>

    <!-- imgcache & jquery -->
    <script src='lib/jquery-2.1.0.min.js'></script>
    <script src='lib/imgcache.js'></script>



    <!-- Local Scripts -->
    <script src="js/app.js"></script>
    <script src="js/controllers.js"></script>
    <script src="js/services.js"></script>

    <!-- Phonegap Dependencies -->
    <script type="text/javascript" src="phonegap.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
    <script type="text/javascript">
        app.initialize();
    </script>
</body>

以及路由的代码

var myApp = angular.module('myApp',[
'ui.router',
'ngTouch',
'ui.bootstrap',
'Controllers',
'Services'
]);
myApp.config(function($stateProvider,$urlRouterProvider,$compileProvider)

//$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);

$urlRouterProvider.otherwise('/login');
$stateProvider.
    state('login',
        url:'/login',
        views:
            'header@':
                templateUrl:'/views/login.header.html'
            ,
            'content@':
                templateUrl:'/views/login.html',
                controller: 'LoginController'
            
        
    ).
    state('tours',
        url:'/tours',
        views:
            'header':
                templateUrl:'/views/tours.header.html',
                controller: 'HeaderController'
            ,
            'content':
                templateUrl:'/views/tours.html',
                controller: 'ToursController'
            
        
    ).
    state('tour',
        url:'/tours/:tourId',
        views:
            'header':
                templateUrl:'/views/header.html',
                controller: 'HeaderController'
            ,
            'content':
                templateUrl: '/views/tour.html',
                controller: 'TourController'
            
        

    ).
    state('buildingTour',
        url:'/buildingTour/:tourId',
        views:
            'header':
                templateUrl:'/views/header.html',
                controller: 'HeaderController'
            ,
            'content':
                templateUrl:'views/building_tour.html',
                controller:'BuildingTourController'
            
        
    ).
    state('buildingTourNotes',
        url:'/buildingTour/:tourId/notes',
        views:
            'header':
                templateUrl:'/views/header.html',
                controller: 'HeaderController'
            ,
            'content':
                templateUrl: 'views/notes.html',
                controller: 'NotesController'
            
        

    ).
    state('buildingTourPhotos',
        url:'/buildingTour/:tourId/photos',
        views:
            'header':
                templateUrl:'/views/header.html',
                controller: 'HeaderController'
            ,
            'content':
                templateUrl:'/views/photos.html',
                controller:'PhotosController'
            
        

    ).
    state('buildingTourDocuments',
        url:'/buildingTour/:tourId/documents',
        views:
            'header':
                templateUrl:'/views/header.html',
                controller: 'HeaderController'
            ,
            'content':
                templateUrl:'/views/documents.html',
                controller:'DocumentsController'
            
        

    ).
    state('buildingTourFloorplans',
        url:'/buildingTour/:tourId/floorplans',
        views:
            'header':
                templateUrl:'/views/header.html',
                controller: 'HeaderController'
            ,
            'content':
                templateUrl:'/views/floorplans.html',
                controller:'FloorplansController'
            
        

    ).
    state('buildingTourRatings',
        url:'/buildingTour/:tourId/ratings',
        views:
            'header':
                templateUrl:'/views/header.html',
                controller: 'HeaderController'
            ,
            'content':
                templateUrl:'/views/ratings.html',
                controller:'RatingsController'
            
        

    );
);

但是,使用 Phonegap Build 服务会生成完全空白的 iOS 和 Android 发行版。使用 Phonegap Build 的调试器检查 html 标记显示标题和内容的 div 最终为空白。

见下图:

我还研究了 UI-Router 的 github 存储库中的问题,并提出了 this。虽然这似乎只适用于 ui-sref 元素,而不是 ui-view 元素。有没有其他人遇到过这个问题或类似的问题?使用传统的角度条件逻辑进行重构以呈现不同的标头将是一种痛苦,这似乎会使代码的可读性/可持续性降低。谢谢!

【问题讨论】:

您好,您是如何设置 Cordova 的引导程序的?也许你必须检查它!,它会导致与 Angular 库发生冲突,因为它还没有准备好。 Ripple 模拟器也已过时!尝试在设备上运行应用程序并检查 LogCat。我将提出一个我在帖子中看到的解决方案。 我无法理解您在这里的意思。 deviceready 调用得到正确处理,因为我使用它通过 Phonegap FileSystem API 在本地存储图像。从 Angular 的标准路由器迁移到 ui-router 是造成这种情况的原因。不过,尝试通过 LogCat 进行调试是一个好点,我会研究一下。 对不起,我以为你的问题是与准备好的设备冲突,因为我有同样的问题并且 AngularJs 抛出异常,所以我解决了在服务中处理它。我不知道是不是构建服务的问题。尝试在本地编译并在设备中调试 【参考方案1】:

Quick awnser: 问题在于模板网址中的初始斜线。删除所有初始斜线,你应该很高兴。

示例:以下代码摘录

templateUrl:'/views/login.header.html'

应改为:

templateUrl:'views/login.header.html'

解释:初始斜线使路径相对于根。当您在浏览器上进行测试时,index.html 可能在http://localhost/index.html 上,因此对/views/login.header.html 的请求会解析为http://localhost/views/login.headers.html,这没关系。

另一方面,当您在 phonegap 生成的应用程序上进行测试时,index.html 可能在file:///android_asset/www/index.html 上,因此请求解析为file:///views/login.headers.html,而这并不存在。如果您从 url 中删除初始斜杠,则路径将相对于您所在的位置,请求将解析为 file:///android_asset/www/views/login.headers.html,它应该可以工作。

【讨论】:

感谢 Eduardo,我之前已经想通了,但完全忘记更新我的帖子了。这确实是正确答案!【参考方案2】:

我知道答案已被接受,但我想添加另一个可能的问题原因:确保您没有启用 html5Mode,并且没有使用 config() 上的前缀。这就是我的问题。

【讨论】:

这个答案需要更多。我没有使用phonegap,只是cordova cli。该项目有 angular 1.5.2 和 ui-router 和其他东西。这救了我。 也救了我。

以上是关于将 Angular UI-Router 与 Phonegap 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

具有基本服务器文件问题的 Angular UI-Router

ngRoute (angular-route.js) 和 ui-router (angular-ui-router.js) 模块有什么不同呢?

Angular 2、TypeScript 和 ui-router - 如何获取状态参数

Angular 1.5,ui-router + 资源 + 组件,stateProvider 找不到组件

ngRoute (angular-route.js) 和 ui-router (angular-ui-router.js) 模块有什么不同呢?

ngRoute (angular-route.js) 和 ui-router (angular-ui-router.js) 模块有什么不同呢?