• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

Ionic 入门:组件服务

一、服务介绍

在本系列 ionic的第一部分和第二 部分中,我们设置了本地开发并构建了几个视图来使用一些 Ionic 组件(例如基本导航和列表组件)加载公园列表。在本教程中,我们将深入研究 Ionic 如何提供许多服务,使您能够以编程方式管理应用程序和界面。

之前,我们演示了 Ionic 如何通过组件提供交互功能,这些组件用作 html 元素(作为 angular 指令实现)。但是,有些界面元素作为用 HTML 实例化的组件没有意义,例如加载器或操作表覆盖。

让我们先来看看服务在您的应用中扮演的角色。我在 Ionic 中确定了三种主要的服务类型:

  • 组件服务

  • 委托服务

  • 辅助服务

组件服务

组件服务支持组件的使用,但不是使用 HTML 来声明它们(就像我们在 中看到的那样ionNavBar),它们是使用javascript管理的。换句话说,您将通过向控制器添加代码来利用这些组件。我们将在下面的示例中使用其中的两个。

将这些服务视为具有生命周期的组件会很有用。通常,您希望它们在特定点加载,并在完成后将它们删除。例如,$ionicModal允许您创建一个模态。模态有一个生命周期,它们会因特定原因而打开和关闭。您可能有一个模式要求用户登录,或者他们可以关闭模型以跳过它,从而完成生命周期。

代理服务

一些组件具有可以修改或管理组件的伴随委托服务。您可能希望在创建组件后以编程方式对其进行操作,而这些服务旨在使之成为可能。它们之所以如此命名,是因为它们将行为委托给组件。

该ionNavBar组件有一个名为 的委托服务$ionicNavBarDelegate。该服务有多种方法,其中一个示例是title()方法,它允许您更新导航栏的标题。每个委托服务可用的功能范围各不相同,但它们应该很容易在文档中通过名称发现。

辅助服务

最后一类是提供某种辅助功能或提供信息的服务。它们中只有少数几个,它们不太适合其他两个类别。一些例子是:

  • $ionicPlatform:帮助您与设备硬件交互

  • $ionicGesture: 允许你处理手势事件

  • $ionicposition: 告诉你元素在屏幕上的位置

这些辅助服务倾向于帮助您开发逻辑或处理交互。他们不会自行生成或修改组件。

我们还将在本教程中查看其他一些内容:

  • css 组件,它们只是可视的,不提供功能逻辑,不像它们的 JavaScript 组件兄弟姐妹

  • 离子事件,我们可以利用它来挂钩事件,例如,当视图正在加载或完成加载时

  • 更多导航功能,便于导航、管理状态以及向导航栏添加按钮

源文件

在本教程中,我们将扩展我们在之前教程中启动的应用程序。提醒一下,该应用程序旨在为用户提供有关其当地公共设施的信息,例如图书馆和公园。该应用程序已经显示了芝加哥的公园列表,现在我们将添加显示加载指示器、查看各个公园详细信息屏幕、打开操作菜单以及实现一些基本共享功能的功能。

您可以在GitHub 上查看已完成的项目。最后一个示例也可供预览。

您可以下载文件或使用 Git 签出。一旦你的机器上有文件,你需要运行npm install 来设置项目。如果您使用 Git 检查代码,如果您重置 repo 以匹配最后一部分通过运行结束的位置,则可以编写代码git checkout –b start。获得文件后,通过运行ionic serve.

2.实现加载指示器

目前,该应用程序加载数据,并且无限滚动组件中会显示一个小圆圈指示器,直到它加载为止。但是,我们实际上想要覆盖整个应用程序,因此应用程序正在加载非常清楚。

该$ionicLoading服务对于覆盖和阻止用户在数据加载之前与应用程序交互非常有用。它是可配置的。例如,您可以声明是否出现加载图标或某些文本,是否需要背景,或者是否应该在一定时间后自动隐藏。您可以在下面的屏幕截图中看到加载程序的运行情况。

Ionic 入门:组件服务  第1张
打开 www/views/places.js 进行一些修改以使用加载器。$ionicLoading首先,我们需要通过添加函数参数将服务注入我们的控制器 。该服务非常简单,它只有两种方法, show()和hide(). 我们可以通过调用您在此片段中看到的方法来显示和隐藏加载程序。

.controller('PlacesController', function($http, $scope, $ionicLoading, Geolocation) {
  var vm = this;
  var base = 'https://civinfo-apis.herokuapp.com/civic/places?type=park&location=' + Geolocation.geometry.location.lat + ',' + Geolocation.geometry.location.lng;
  var token = '';
  vm.canLoad = true;
  vm.places = [];
 
  $ionicLoading.show();
 
  vm.load = function load() {
    var url = base;
    if (token) {
      url += '&token=' + token;
    }
 
    $http.get(url).then(function handleResponse(response) {
      vm.places = vm.places.concat(response.data.results);
      token = response.data.next_page_token;
 
      if (!response.data.next_page_token) {
        vm.canLoad = false;
      }
      $scope.$broadcast('scroll.infiniteScrollComplete');
      $ionicLoading.hide();
    });
  };
});

加载控制器后立即调用该$ionicLoading.show() 方法,这意味着它会立即触发。现在我们需要告诉加载器在数据加载完成后隐藏,正如您在$broadcast.

您可能会注意到,$ionicLoading.hide()每次加载数据时都会调用该方法。这不是问题。由于加载程序已经隐藏,因此此调用没有任何效果。

我们现在已经实现了一个 Ionic 服务。很简单。正确的?有些稍微复杂一些,我们将使用操作表处理另一个示例。不过,在我们开始之前,我们希望扩展我们的应用程序,使其具有两个视图,用于笔记列表和单独查看笔记。

3.添加笔记视图

我们的下一步是创建一个新视图,以显示有关特定公园的更多详细信息。信息可能因公园而异,但我们将专注于获取图像、网站、电话和地址信息。添加此视图的结果显示在此处。

Ionic 入门:组件服务  第2张要创建一个新视图,请在www/views/place/place.js创建一个文件,并包含您在下面看到的内容。这是place视图的控制器和状态定义。

angular.module('App')
.config(function($stateProvider) {
  $stateProvider.state('place', {
    url: '/places/:place_id',
    controller: 'PlaceController as vm',
    templateUrl: 'views/place/place.html',
    resolve: {
      Place: function($http, $stateParams) {
        var url = 'https://civinfo-apis.herokuapp.com/civic/place?place_id=' + $stateParams.place_id;
        return $http.get(url);
      }
    }
  });
})
.controller('PlaceController', function($scope, Place) {
  var vm = this;

  vm.place = Place.data.result;
});

如果您查看该config() 方法,您会发现我们正在声明一个新状态。这是运行中的 ui-router,因此您应该查阅ui-router 文档以了解有关声明状态的所有详细信息。

对象定义显示我们使用的 URL 为/places/:place_id. 当你看到前面有冒号的部分 URL 时,例如 :place_id,它会将这部分路径标记为状态参数。状态能够提取值并使用 $stateParams对象将其提供给您。例如,/places/12345将导致 $stateParams.place_id = '12345'.

您之前已经看到了定义的其他部分,除了resolve属性。这是一项允许您在创建状态之前请求调用各种函数的功能。它接受键和函数值的对象,所以这里我们Place将键作为键,函数的结果将被分配给它。

在函数中,它可以接受要注入的参数,类似于您可以使用控制器执行的操作。在这里,$http和$stateParams服务被注入。然后,该函数使用place_id通过 URL 传递的值并构建并返回 HTTP 请求。这基本上是在地点视图中所做的,除了控制器执行此操作。

解析功能足够聪明,可以确定如果您返回一个承诺,它将等待该承诺在创建状态之前解决。换句话说,返回一个加载数据的承诺,并且 ui-router 在创建状态并将其传递给控制器$http.get()之前等待数据可用。Place解析功能对于在您的应用程序中预加载数据非常有用,这是如何利用它的一个相当基本的示例。

现在我们已经定义了状态,声明了控制器并将结果数据从Place(这是在状态中解决的)分配给vm.place. 我们还需要为这种状态制作模板,因此在www/views/place/place.html 处创建一个新文件并在其中添加以下内容。

<ion-view view-title="{{vm.place.name}}">
  <ion-content>
    <div class="card" ng-if="vm.place">
      <div class="item item-text-wrap item-icon-left">
        <i class="icon ion-map"></i> {{vm.place.formatted_address}}</p>
      </div>
      <div class="item item-image" ng-if="vm.place.photos[0].photo_reference">
        <img ng-src="{{'https://civinfo-apis.herokuapp.com/civic/photo?photo_id=' + vm.place.photos[0].photo_reference}}">
      </div>
      <a ng-if="vm.place.website" class="item item-icon-left" ng-href="{{vm.place.website}}" target="_system">
        <i class="icon ion-link"></i> {{vm.place.website}}
      </a>
      <a ng-if="vm.place.formatted_phone_number" class="item item-icon-left" ng-href="tel://{{vm.place.formatted_phone_number}}">
        <i class="icon ion-ios-telephone"></i> {{vm.place.formatted_phone_number}}
      </a>
    </div>
  </ion-content>
</ion-view>

该模板首先使用ionView包装内容,因此 Ionic 导航系统可以正确跟踪它。它还根据地点的名称分配标题。包装器ionContent包含主要内容,您会注意到模板使用 CSS 类而不是元素来创建卡片组件。

在上一部分中,我们讨论了一些组件如何只是 CSS 类。这张卡就是其中一个例子。从概念上讲,它就像一个列表。内部内容像列表一样垂直堆叠,但样式看起来更像一张卡片。这利用了卡片样式,其中包括图像支持、图标和文档中提供的其他简洁布局等功能。

使用了一些ngIf指令,因为不能保证返回的数据会有电话号码或网站。该 ngIf 指令确保不显示空值。它还使用ngHreforngSrc来正确建立链接。

您还会注意到该tel://协议的使用,当在电话上使用该协议时,应提示用户在选择该号码时拨打该号码。这是一个方便的功能,易于使用并且可以很好地集成在物理设备上。根据您的设置,您计算机上的某些程序(例如 Skype)也可能会尝试为您处理拨打电话。

这应该给我们一个工作视图,但我们如何导航到它?我们需要做一些小的修改,以使导航在地点视图中工作。

4.在视图之间导航

ui-router 提供了一个ui-sref指令,用于将项目链接到另一个状态。在这种情况下,我们希望地点视图列表中的每个项目都链接到相应的地点视图。

打开 www/views/places/places.html 并添加指令以链接到每个地方。ionItem在此处使用新属性更新。

<ion-item ng-repeat="place in vm.places" class="item-avatar" ui-sref="place({place_id: place.place_id})">

该ui-sref指令有一种格式,您可以通过它的名称链接到另一个州,而不是像您使用href. 这很方便,因为 URL 可能会更改。它还可以接受用于构建 URL 的参数,在我们的例子中,我们想要传递place.place_id属性。将ui-sref属性作为对象, state-name({param: value})语法也是如此。

现在预览应用程序并选择一个公园,它将导航到新place视图,您可以查看地址栏以查看 URL 添加place_id值。然而,我们现在遇到了一个问题。我们如何回到列表中?

我们使用该ionNavBackButton功能为我们提供了一个自动后退按钮。打开 www/index.html并在ionNavBar. 这会添加一个返回按钮,该按钮仅在有可返回的位置时显示。

<ion-nav-bar class="bar-balanced">
  <ion-nav-back-button class="button-clear">
    <i class="ion-arrow-left-c"></i> Back
  </ion-nav-back-button>
</ion-nav-bar>

Ionic 的导航非常智能,可以在您使用应用程序时跟踪历史记录。如果有前一个视图要返回,它将显示返回按钮。否则,它只会被隐藏。

我们还想声明places 视图不应该显示后退按钮,我们可以通过在www/views/places/places.htmlhideBackButton中添加指令 来做到这一点。

<ion-view view-title="Local Parks" hide-back-button="true">

在浏览器中进行开发和预览时,有时历史记录会被重置。例如,当您在地点视图中并在编辑器中保存更改时,浏览器会自动重新加载并重置历史记录。在这种情况下,后退按钮不会按预期显示。您可以通过返回列表并刷新以设置历史记录来解决此问题。

我们已经取得了不错的进展,但是现在,当您点击列表中的某个项目时,它会等待转换到新视图,直到 API 调用返回数据。它在您看来可能很快,但有时如果 API 很慢,它可能会很慢。这可能会导致某人认为应用程序卡住、速度缓慢,或者它没有注册他们的点击,因为它没有立即开始对点击做出反应。我们通过一些生命周期事件来解决这个问题,这些事件帮助我们设置加载器以在此期间显示。

5.在过渡期间添加加载器

为了提供更好的用户体验,我们将使用该$ionicLoading服务覆盖应用程序,同时为地点视图加载数据。为了知道何时显示和隐藏加载器,我们使用生命周期事件。

这些事件基于导航事件触发,例如进入视图之前/之后或离开视图之前/之后。您可以在这些时间点执行任何可能需要的操作,例如重置某些数据或使用它来提交使用信息。

为了演示它,让我们向places 视图添加一个事件***器,当您开始导航到place 视图时处理触发加载程序。打开 www/views/places/places.js并将以下内容添加到控制器中。您还需要确保$scope在控制器函数参数中声明它以便它可用。

$scope.$on('$ionicView.beforeLeave', function() {
  $ionicLoading.show();
});

这是一个监听事件的作用域事件监听器$ionicView.beforeLeave(参见Angular 作用域事件)。Ionic 将此事件广播到您的控制器并调用此处声明的匿名函数。这个函数只是调用$ionicLoading.show()方法来打开加载器。

这会触发加载程序在用户点击项目时立即出现。现在我们向 place 视图添加一个类似的片段,用于在视图完成加载时处理隐藏加载器。打开 www/views/place/place.js并将以下内容添加到控制器中。您需要同时添加$ionicLoading和 $scope 到控制器功能参数,因为它们当前没有被注入。

$scope.$on('$ionicView.afterEnter', function() {
  $ionicLoading.hide();
});

这会***视图完成时触发的不同范围事件,并调用该函数来隐藏加载器。加载程序显示在用户点击要查看的位置到视图完全加载之间的时间。您可以尝试其他事件并查看它们何时触发。

我们在本教程中做的最后一件事是设置一个操作表共享按钮,允许您发布到 Twitter、Facebook 或电子邮件并共享公园信息。

6.使用 Action Sheet 服务的分享按钮

操作表对于提供附加选项列表非常有用。目的通常是针对您想要呈现分组的操作列表的情况,在我们的示例中,它是共享公园信息的方式列表。我们将构建的操作表如下所示。

Ionic 入门:组件服务  第3张操作表服务比加载服务稍微复杂一些,因为它处理配置和用户输入。打开 www/views/place/place.js 并将这个新方法添加到您的控制器中。您还需要确保将$ionicActionSheet其注入您的控制器。

vm.openSheet = function() {
  var sheet = $ionicActionSheet.show({
    titleText: 'Share this place',
    buttons: [
      { text: 'Share via Twitter' },
      { text: 'Share via Facebook' },
      { text: 'Share via Email'}
    ],
    cancelText: 'Cancel',
    buttonClicked: function(index) {
      if (index === 0) {
        window.open('https://twitter.com/intent/tweet?text=' +
          encodeURIComponent('I found this great place! ' + vm.place.url));
      } else if (index === 1) {
        window.open('https://www.facebook.com/sharer/sharer.php?u=' + vm.place.url);
      } else if (index === 2) {
        window.open('mailto:?subject=' + encodeURIComponent('I found this great place!') + '&body=' + vm.place.url);
      }
      sheet();
    }
  });
};

该openSheet()方法负责创建操作表。它通过调用 来做到这一点$ionicActionSheet.show(),它返回一个存储在sheet. 这允许您在稍后通过调用完成工作表时关闭工作表sheet()。该show()方法接受一个具有许多我们将分解的属性的对象。有几个遵循此模式的 Ionic 服务示例,例如模态框和弹出框,因此您始终可以处理关闭它们。

工作表使用属性管理标题 titleText,通常用于通知用户如何使用按钮。该 cancelText 属性接受用于启用取消按钮的字符串。如果您不声明这一点,则不会选择取消按钮。您也可以通过点击按钮外的背景来取消。

要声明按钮,请使用 buttons 属性,该属性是具有text属性的对象数组。它们按照声明的顺序显示,因此请相应地对它们进行排序。

该buttonClicked属性接受一个函数,并传递所选按钮的索引(如在 中声明的那样buttons)。因此,您可以根据传递的索引确定要做什么。在此功能中,检查索引并打开 Facebook、Twitter 或用于mailto:触发电子邮件客户端

它可能会在 Facebook、Twitter 或电子邮件应用程序中打开这些链接,具体取决于用户设置和设备,但它至少会在您的应用程序之外(在外部浏览器中)打开这些链接。最后一步是调用sheet()关闭操作表的方法。

操作表现在已准备好执行操作,但我们仍需要添加一个按钮来触发该表。为此,我们将导航栏按钮添加到调用 vm.openSheet(). 打开 www/views/place/place.html并在和之间 添加ionNavButtons代码段。ionViewionContent

<ion-view view-title="{{vm.place.name}}">
  <ion-nav-buttons side="right">
    <button class="button button-clear" ng-click="vm.openSheet()">
      <i class="icon ion-ios-upload-outline"></i>
    </button>
  </ion-nav-buttons>
  <ion-content>

这是另一个有用的 Ionic 导航功能,它允许您使用ionNavButtons. 里面的任何按钮都会添加到导航栏,您可以配置它们出现在哪一侧。

此时,一切正常。用户可以打开操作表与朋友分享公园。

结论

在本教程中,我们介绍了 Ionic 服务及其使用方式。在此过程中,我们发现了许多其他 Ionic 功能:

  • 离子服务在控制器中被调用,并且通常具有独立于当前视图的生命周期。

  • 该$ionicLoading服务可用于在您的应用加载数据或必须以其他方式阻止用户界面时显示和隐藏加载指示器。

  • 该$ionicActionSheet服务向用户提供覆盖应用程序的按钮列表,以提供对重要操作的轻松访问。

  • 离子导航功能还包括在ionNavBackButton可以返回时自动显示返回按钮。ionNavButtons 允许您将导航栏按钮添加到特定视图。

  • Ionic 有 CSS 组件,比如卡片,没有特殊的交互功能,仅通过声明 CSS 类来使用。

在下一部分中,我们将更深入地研究 Ionic 的一些导航功能。



文章目录
  • 一、服务介绍
    • 组件服务
    • 代理服务
    • 辅助服务
    • 源文件
  • 2.实现加载指示器
  • 3.添加笔记视图
  • 4.在视图之间导航
  • 5.在过渡期间添加加载器
  • 6.使用 Action Sheet 服务的分享按钮
  • 结论