Angular JS (Angular.JS) 是一组用来开发Web页面的框架、模板以及数据绑定和丰富UI组件。它支持整个开发进程,提供web应用的架构,无需进行手工DOM操作。
AngularJS是为了克服HTML在构建应用上的不足而设计的。HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了。这里AngularJS就应运而生,弥补了HTML的天然缺陷,用于构件Web应用等。
TL;DR
这篇文章讲解了三种根据 service 的状态更新 directive 的做法。分别是 $watch 表达式,事件传递,和 controller 的计算属性。
问题
我有一个 readerService ,其中包含一些状态信息(比如连接状态和电量)。现在我需要做一个 directive 去展示这些状态。因为它只需要从 readerService 中获取数据,不需要任何外部传值,所以我直接把 service 注入进去。但如何更新就成了一个问题。
service 的代码如下。
const STATUS = {DETACH: 'DETACH',ATTACH: 'ATTACH',READY: 'READY'}class ReaderService {constructor() {this.STATUS = STATUS// The status will be changed by some callbacksthis.status = STATUS.DETACH}}angular.module('app').service('readerService', readerService)
directive 代码如下:
angular.module('app').directive('readerIndicator', (readerService) => {const STATUS = readerService.STATUSconst STATUS_DISPLAY = {[STATUS.DETACH]: 'Disconnected',[STATUS.ATTACH]: 'Connecting...',[STATUS.READY]: 'Connected',}return {restrict: 'E',scope: {},template: `<div class="status">{{statusDisplay}}</div>`,link(scope) {// Set and change scope.statusDisplay here}}})
我尝试过以下几种办法,下面一一介绍。
方法一:$watch
第一个想到的方法就是在 directive 中用 $watch 去监视 readerService.status 。因为它不是 directive scope 的属性,所以我们需要用一个函数来包裹它。Angular 会在 dirty-checking 时计算和比较新旧值,只有状态真的发生了改变才会触发回调。
// In directivelink(scope) {scope.$watch(() => readerService.status, (status) => {scope.statusDisplay = STATUS_DISPLAY[status]})}
这个做法足够简单高效,只要涉及 readerService.status 改变的代码会触发 dirty-checking ,directive 就会自动更新。service 不需要修改任何代码。
但如果有多个 directive 的属性都受 service status 的影响,那 $watch 代码就看得比较晦涩了。尤其是 $watch 修改的值会影响其他的值的时候。比如:
// In directivelink(scope) {scope.$watch(() => readerService.status, (status) => {scope.statusDisplay = STATUS_DISPLAY[status]scope.showBattery = status !== STATUS.DETACH})scope.$watch('showBattery', () => {// some other things depend on showBattery})}
新闻热点
疑难解答
图片精选