Prism 4 文档 ---第9章 松耦合组件之间通信

当构建一个大而负责的应用程序时,通用的做法时将功能拆分到离散的模块程序集中。将模块之间的静态引用最小化。这使得模块可以被独立的开发,测试,部署和升级,以及它迫使松散耦合的沟通。

当在模块之间通信时,你需要知道不同通信方式之间的区别,那样你才能确定哪种方式对于你的特定的场景最合适,Prism类库提供了以下几种通信方式:

  • 命令。当希望对于用户的交互马上采取动作时使用。
  • 事件聚合。用于ViewModel,展现层,或者控制之间没有所期望的直接动作时。
  • 区域上下文。使用它可以提供宿主和宿主区域的View之间上下文信息。这种方式与DataContext有些相似,但是不依赖与DataContext。
  • 共享的服务。调用者可以调用服务中的一个可以引发接收消息者事件的方法。当以上方式都不能使用时可使用这种方式。

命令

如果你需要对用户的手势做出回应,例如一个命令调用的点击(例如,一个按钮或者菜单项),并且如果你想要基于业务逻辑使得调用变得可用,可以使用命令。

WPF提供了RoutedCommand,它在命令调用之间联系非常擅长,例如菜单项和按钮与可视化树中的具有键盘焦点的当前项相关的命令处理。

然而,在一个组合的场景中,命令处理经常是在一个没有任何与可视化树相关联的元素或者并非焦点元素的ViewModel中。为了支持这种场景,Prism类库提供了DelegateCommand,它允许你在命令执行是调用一个委托方法,同时也提供了CompositeCommand,它允许你组合多个命令。这些命令与内建支持的RoutedCommand不同,它将会路由命令执行并且沿着可视树向上和向下处理。这允许你在可视树中某一点触发一个命令,在一个更高的级别处理这个命令。

CompositeCommandICommand接口的一个实现,所以它可以绑定调用者。CompositeCommands可以与几个子命令相关联;当CompositeCommand被调用时,子命令也会被调用。

CompositeCommands支持启用(enablement)。CompositeCommands监听了每一个关联的命令的CanExecuteChanged事件,它可以通过引发这个事件来通知它的调用者(们)。调用者(们)通过调用CompositeCommandCanExecute方法来对这个事件做出反应。CompositeCommand然后调用它的每个子命令的CanExecute方法。如果任何子命令的CanExecute方法返回值为falseCompositeCommand将会返回false,这将会使得调用不可用。

它在模块间的通信反面是如何帮助你的?基于Prism类库的应用程序可以获得在Shell中定义的模块间的CompositeCommands,例如SaveSave All Cancel。模块可以将他们自己的命令注册到这些全局的命令中病参与它们的执行。

注意:

关于WPF 路由事件和路由命令

路由事件是可以调用元素树中多个监听者的处理逻辑的一类事件,而不是仅仅通知某个事件的直接订阅对象。WPF路由命令在可视树中的UI元素间传力命令消息。但是可视树以外的元素不会收到这些消息,因为它们只会从焦点元素向上冒泡或者向下传递或者传递到指定状态的目标对象。路由事件可以用于元素树内元素的通信,因为路由事件的数据对于路由中的每个元素都是长期保存的。一个元素可以改变事件数据中的一些内容,这些改变的内容也可以被路由中的下一个元素访问到。因此。在以下场景中你应该使用WPF路由事件:在一个通用的根中定义通用的处理或者定义自定义控件类时。

创建一个委托命令

为了创建一个委托命令,在ViewModel的构造方法中实例化一个DelegateCommand字段,然后暴露为一个ICommand属性。

public class ArticleViewModel : NotificationObject
{
    private readonly ICommand showArticleListCommand;

    public ArticleViewModel(INewsFeedService newsFeedService,
                            IRegionManager regionManager,
                            IEventAggregator eventAggregator)
    {
        this.showArticleListCommand = new DelegateCommand(this.ShowArticleList);
    }

    public ICommand ShowArticleListCommand
    {
        get { return this.showArticleListCommand; }
    }
}

创建一个组合命令

为了创建一个组合命令,在构造方法中实例化一个CompositeCommand字段,为其添加命令,然后将它暴露为一个ICommand属性。

public class MyViewModel : NotificationObject
{
    private readonly CompositeCommand saveAllCommand;

    public ArticleViewModel(INewsFeedService newsFeedService,
                            IRegionManager regionManager,
                            IEventAggregator eventAggregator)
    {
        this.saveAllCommand = new CompositeCommand();
        this.saveAllCommand.RegisterCommand(new SaveProductsCommand());
        this.saveAllCommand.RegisterCommand(new SaveOrdersCommand());
    }

    public ICommand SaveAllCommand
    {
        get { return this.saveAllCommand; }
    }
}

使一个命令全局可用

通常,为了创建一个全局可用的命令,创建一个DelegateCommand或者CompositeCommand的示例,并将其通过一个静态类对外暴露。

public static class GlobalCommands
{
    public static CompositeCommand MyCompositeCommand = new CompositeCommand();
}

在你的模块中,将子命令同全局命令关联。

GlobalCommands.MyCompositeCommand.RegisterCommand(command1);
GlobalCommands.MyCompositeCommand.RegisterCommand(command2);

注意:

为了提升代码的可测试性,你可以使用一个代理类来访问全局命令并在测试中模拟这个代理类。

绑定到一个全局可用的命令

下面的diamond示例展示了在WPF中如何将一个命令绑定到一个按钮。

<Button Name="MyCompositeCommandButton" Command="{x:Static local:GlobalCommands.MyCompositeCommand}">Execute My Composite Command </Button>

Silverlight没有提供对x:static的支持,所以在Silverlight中执行以下几步来绑定一个命令到一个按钮:

  • 在View Model中,创建一个公共属性从静态类中获取命令。代码如下。
public ICommand MyCompositeCommand
{
    get { return GlobalCommands.MyCompositeCommand; }
}
  • 通常,通过View的DataContext传递Model(这是在View的后台代码中实现的)。下面的代码展示了如何将Model设置为View的DataContext,通过这样做,你可以在XAML中声明式将命令绑定到View的控件上。
view.DataContext = model;
  • 确保下面的XML命名空间添加到了View的XAML文件的跟元素中。
xmlns:prism="clr-namespace:Microsoft.Practices.Prism.Commands;assembly=Microsoft.Practices.Prism"
  • 在Silverlight中通过使用Click.Command附加属性将命令绑定到按钮上。代码如下。
<Button Name="MyCommandButton" prism:Click.Command="{Binding MyCompositeCommand}"/>Execute MyCommand</Button>

注意:

另一种方式是将命令作为资源存储到App.xaml文件的Application.Resources节点。然后,在设置了资源的必须创建的View中你可以设置 prism: Click.Command="{Binding MyCompositeCommand, Source={StaticResource GlobalCommands}}" 来添加一个命令的调用。

区域上下文

将会有大量的你可能想要在承载了Region的View和在Region中的View之间共享上下文信息的场景。例如,一个View的细节展示了一个业务实体并且暴露了一个region来显示业务实体的额外详细信息。Prism类库使用一个名称为RegionContext概念在Region的宿主和Region中加载的View之间共享一个对象,如下图所示。

基于这个场景,你可以选择共享信息的的一个方面(例如一个标识)或者一个共享的Model。View可以检索RegionContext,然后标记变化通知。View也可以改变RegionContext的值。这里有关于暴露和消费RegionContext的几种方式:

  • 可以在XAML中将RegionContext暴露给一个Region。
  • 可以在代码中将RegionContext暴露给一个Region。
  • 可以从region中的一个内部View消费RegionContext

注意:

Prism类库目前仅支持从region中的一个内部View消费RegionContext,这个View需要是一个DependencyObject。如果这个View不是一个DependencyObject(例如,你正使用WPF自动的数据模板并且直接在Region中添加View),考虑创建一个自定义的RegionBehavior来转发RegionContext给你的View对象。

注意:

    关于数据上下文属性

数据上下文是一个允许元素集成他们父元素关于用于绑定的数据源信息的概念。子元素自动继承父元素的DataContext。数据沿着可视树向下流转。在Silverlight中将ViewModel绑定的Vied的最好的方式就是使用DataContext属性;这就是为什么在大多数情况下使用DataContext来存储ViewModel的原因。因此,除非是非常简单的View,不推荐使用DataContext属性作为松耦合的不同View之间的通信机制。

共享的服务

模块间通信的另一种方法是通过共享的服务。当模板被加载,模块向服务定位器中添加它们的服务。通常,从一个服务定位器中通过通用接口类型注册和检索服务。这使得模块可以使用其他模块提供的服务而不需要模块的静态引用。服务实例在模块间是共享的,所以你可以在模块间共享数据已经传递消息。

在Stock Trader RI中,Market模块提供了IMarketFeedService接口的实现。Position模块通过使用提供了服务定位和分辨的应用程序依赖注入容器的Shell消费这些服务,IMarketFeedService意在被其他模块消费,所以在StockTraderRI.Infrastructure通用程序集中可以被找到,但是这个接口的具体实现不需要被共享,所以它被之间订阅在了Market模块并且可以被单独的升级。

想要知道这些服务是如何被注册到依赖注入容器Unity中的,查看MarketModule.cs文件,如下所示,Position模块的ObservablePosistion通过构造注入来接收IMarketFeedService服务。

protected void RegisterViewsAndServices()
{
   _container.RegisterType<IMarketFeedService, MarketFeedService>(new ContainerControlledLifetimeManager());
   //...
}

这样有助于模块间的通信,因为服务的消费这不需要服务提供模块的静态的引用。这个服务可以用于在模块间发送和接收数据。

事件聚合

Prism类库提供了事件机制能让应用程序中的松耦合组件相互通信。这种机制建立在事件聚合服务上,允许发布者和订阅者通过事件通信,不许要彼此直接引用

EventAggregator提供了多点传送发布/订阅功能。这意味着可能有可以触发同一事件多个发布者和可以监听同一事件的订阅者。考虑使用EventAggregator 来发布一个事件,贯穿多个模块和发送消息在业务逻辑代码间,像控制器和展示。

例如,在Stock Trader RI中,当Process Order 按钮别点击而且订单被成功处理,在这种情况下,同时其他模块需要知道订单被成功处理,以便它们能更新它们的

View。

Prism类库创建的事件是类型事件。这意味着你能在运行应用程序之前通过编译类型检测错误的优点,Prism类库中,EventAggregator允许订阅者

或发布者定位指定的EventBase.事件聚集允许多个发布者和多个订阅者。正如下面的插图所示。

注意:

    关于.NET Framework 事件

使用.NET Framework事件是最简单和直观的方式用于非松散耦合需求的组件。.NET Framework 事件实现了发布-订阅模式,但是是对一个对象订阅,你需要直接引用那个对象, 这个在复杂的应用程序中,这个对象通常属于另一模块。这样导致的后果就是一种紧耦合设计。因此,.NET Framework事件用于模块内的通信而不是模块间的通信。如果你使用.NET Framework 事件, 你不得不非常小心内存泄露,特别是如果你有一个非静态的或者短暂的组件订阅了一静态或者长时间存在的事件。如果你没有取消订阅的订阅者,发布者将保存订阅者,而且阻止订阅者被垃圾回收。

IEventAggregator

    EventAggregator类在容器中被作为一个服务并且可以通过IEventAggregator接口检索。事件聚合负责定位或者构建事件以及保持系统中事件集合。

public interface IEventAggregator
{
   TEventType GetEvent<TEventType>() where TEventType : EventBase;
}

EventAggregator在第一次被构造的时候构建事件。这减轻了发布者或订阅者在确定该事件是否是可用的的负担。

CompositePresentationEvent

发布者和订阅者之间的关联工作实际是CompositePresentationEvent类在起作用。它是Prism类库中包含的EventBase类的唯一的实现类。这个类维护这订阅者的列表以及处理调度给订阅者的事件。

    CompositePresentationEvent是一个要求有效载荷(payload)类型定义为通用类型的通用类。这有助于保证在编译时,发布者和订阅者为成功的事件集合提供了正确的方法。下面的代码展示了一个定义CompositePresentationEvent类的部分代码。

public class CompositePresentationEvent<TPayload> : EventBase
{
    ...
    public SubscriptionToken Subscribe(Action<TPayload> action);
    public SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption);
    public SubscriptionToken Subscribe(Action<TPayload> action, bool keepSubscriberReferenceAlive)
    public virtual SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive);
    public virtual SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate<TPayload> filter);
    public virtual void Publish(TPayload payload);
    public virtual void Unsubscribe(Action<TPayload> subscriber);
    public virtual bool Contains(Action<TPayload> subscriber)
    ...
}

创建和发布事件

接下来的几节介绍了如何使用IEventAggregator接口实现CompositePresentationEvent类的创建,发布和订阅

创建一个事件

    CompositePresentationEvent<TPayload>意在作为应用程序或者模块事件的基类。TPayLoad是有效事件的类型。有效载荷(payload)是在事件发布后将会传递给订阅着的参数。

例如,下面的代码展示了Stock Trader RI中的TickerSymbolSelectedEvent类,有效载荷是一个包含了公司标志的字符串。注意这个类的实现是空的。

public class TickerSymbolSelectedEvent : CompositePresentationEvent<string>{}

注意:

在一个组合的应用程序中,事件是经常在多个模块间共享的,所以,它们被定义在了一个公共的位置,在Stock Trader RI中看,定义在了 StockTraderRI.Infrastructure 项目中。

发布一个事件

发布者通过引发一个从EventAggregator检索的事件,调用Publish方法。为了获取EventAggregator,你可以通过在类的构造方法中增加一个IEventAggregator类型的参数来使用依赖注入。

例如,下面的代码演示了TickerSymbolSelectedEvent的发布。

this.eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish("STOCK0");

订阅事件

订阅者可以通过使用CompositePresentationEvent类的可用的重载的任意一个Subscribe方法来增加一个事件。使用下面的标准带帮助你决定那种操作最适合你的需要:

  • 如果你需要在收到事件时能够更新UI元素,订阅在UI 线程上接收事件
  • 如果你需要筛选一个事件,当订阅时提供一个筛选的委托
  • 如果你关系事件的性能,考虑在订阅时使用一个强引用委托,并且手动的从CompositePresentationEvent中取消订阅。
  • 如果以上都不试用,使用一个默认的订阅。

接下来的几节讲述这些选择。

在UI线程订阅

经常,订阅者需要在事件的响应中更新UI元素。在WPF和Silverlight中,只有UI线程才能更新UI元素。

默认情况,订阅者在发布者的线程中接收事件。如果发布者在UI线程中发送事件,订阅者可以更新UI,然而,如果发布者线程是后台线程,订阅者将不能直接更新UI元素。在这种情况下,订阅者需要需要安排使用Dispatcher类的UI线程上的更新。

Prism类库提供的CompositePresentationEvent可以帮助订阅者自动的在UI线程上接收事件,下面的代码展示了在订阅过程中指明。

public void Run()
{
   ...
   this.eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews, ThreadOption.UIThread);
);
}

public void ShowNews(string companySymbol)
{
   this.articlePresentationModel.SetTickerSymbol(companySymbol);
}

下面的选项对于ThreadOption可以使用:

  • PublisherThread.使用这个设置,在发布者进程中接收事件,这是默认设置。
  • BackgroundThread. 使用这个设置在.NET Framework线程池中异步接收事件。
  • UIThread. 使用这个设置在UI线程接收事件。

订阅筛选

订阅者可能不需要处理发布者每个事件的示例。在这些情况下,订阅者可以使用filter参数。filter参数是System.Predicate<TPayLoad>类型的,并且是一个当事件发布后如果发布的事件的有效载荷与标准要求的设置参数匹配决定调用订阅这回调的委托。如果有效载荷没有满足指定的标准,订阅者的回调委托不会被执行。

经常,filter被应用为lambda表达式,如下代码所示:

FundAddedEvent fundAddedEvent = this.eventAggregator.GetEvent<FundAddedEvent>();

fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, false,
fundOrder => fundOrder.CustomerId == this.customerId);

注意:

Silverlight不支持lambda表达式或匿名委托的的弱引用。

对于Silverlight,你需要调用分离的功能方法,如下代码所示。

public bool FundOrderFilter(FundOrder fundOrder)
{
    return fundOrder.CustomerId == this.customerId;
}
...

FundAddedEvent fundAddedEvent = this.eventAggregator.GetEvent<FundAddedEvent>();

subscriptionToken = fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, false, FundOrderFilter);

注意:

    Subscibe方法返回一个Microsoft.Practices.Prism.Events.SubscriptionToken类型的订阅标识,它可以在后面用于移除订阅事件。这个标识在你使用匿名委托或者lambda表达式作为回调委托的时候或者使用不同filter订阅相同事件的时候非常有用。

注意:

不推荐在回调委托中修改有效载荷对象,因为在一些线程同时可能会访问有效载荷对象。要保证有效载荷的不变来避免出现错误。

使用强引用订阅

如果你在一个短时间内引发多个事件并且关心它们的性能,你可能需要使用一个强引用委托来订阅。如果你那样做,你需要在销毁订阅者的时候手动的取消对事件的订阅。

默认情况下,CompositePresentationEvent维护着一个与订阅者处理逻辑和订阅筛选逻辑的弱引用。这就意味这,CompositePresentationEvent拥有的引用不会阻止垃圾回收机制对于订阅者的回收,使用弱引用可以减轻订阅者对于取消订阅的负担以及允许正确的垃圾回收。

然而,维护者这种弱引用相比相应的强引用要慢。对于大多数的应用程序,将不会主要这点性能。但是,如果你的应用程序在短时间内发布了大量的事件,你需要使用CompositePresentationEvent的强引用。如果你使用了强引用,你的订阅者需要能够在当订阅对象不在使用时去掉订阅并正确的回收它。

为了订阅一个强引用,在Subscribe方法中使用keepSubscriberReferenceAlive参数,如下所示。

FundAddedEvent fundAddedEvent = eventAggregator.GetEvent<FundAddedEvent>();

bool keepSubscriberReferenceAlive = true;

fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, keepSubscriberReferenceAlive, fundOrder => fundOrder.CustomerId == _customerId);

    keepSubscriberReferenceAlive参数是bool类型的:

  • 当被设置为true时,事件的实例保存这订阅者示例的强引用,因此,不允许它被垃圾回收。有关如果取消订阅的更多内容,参考本章中接下来的“取消订阅事件”一节。
  • 当被设置为false时(参数缺省时的默认值),事件的实例维护着对订阅者的弱引用,因此,在没有对它的引用时它们可以被回收来销毁订阅者实例。当订阅者实例被回收,事件也就自动的取消订阅了。

默认订阅

作为最小的或者默认的订阅,订阅者必须提供一个接收事件通知的适当的回调方法的签名。例如,TickerSymbolSelectedEvent的处理逻辑要求这个方法需要一个字符串参数,如下所示。

public void Run()
{
   ...
   this.eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews);
}

public void ShowNews(string companySymbol)
{
   articlePresentationModel.SetTickerSymbol(companySymbol);
}

取消订阅事件

如果订阅者不在想要接收事件,你可以通过订阅者的处理逻辑来取消订阅也可以通过使用一个订阅标识来取消订阅。

下面代码展示了如何在处理逻辑中直接的取消订阅。

FundAddedEvent fundAddedEvent = this.eventAggregator.GetEvent<FundAddedEvent>();

fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.PublisherThread);

fundAddedEvent.Unsubscribe(FundAddedEventHandler);

下面的代码展示了如何使用一个订阅标识取消订阅,这个标识是由Subscibe方法的返回参数提供的。

FundAddedEvent fundAddedEvent = this.eventAggregator.GetEvent<FundAddedEvent>();

subscriptionToken = fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, false, fundOrder => fundOrder.CustomerId == this.customerId);
fundAddedEvent.Unsubscribe(subscriptionToken);

更多信息

有关弱引用的更过信息,请查看MSDN上的"Weak References": http://msdn.microsoft.com/en-us/library/ms404247.aspx .

时间: 2024-09-28 20:39:15

Prism 4 文档 ---第9章 松耦合组件之间通信的相关文章

Prism 4 文档 ---第10章 Silverlight和WPF之间共享代码

本主题帮助你理解来自Prism的多目标和它的优缺点.多目标的代码针对两个不同的平台有大致相同的代码库.这允许同时保持代码尽可能多一样能够产生针对两种不同技术的二进制文件.在这种情况下,本节介绍的技术是WPF和Silverlight.本主题包含了一些你在使用这些技术开发多目标应用程序的时候的注意事项. 目标和有点 当在编写具有相似功能和能力的WPF和Silverlight应用程序的时候,努力使用一个代码库很有意义.尽管WPF和Silverlight平台非常相似,但他们只有有限的二进制兼容性.仅Si

Prism 4 文档 ---第8章 导航

作为同用户具有丰富的交互的客户端应用程序,它的用户界面(UI)将会持续不断的更新来反映用户工作的当前的任务和数据.用户界面可以进行一段时间相当大的变化作为用户交互的应用程序中完成各种任务.通过该应用程序协调这些用户界面的变化的过程通常被称为导航. 经常,导航意味着某些控件将会从UI中移除,其他的控件将会被添加到UI中.在另外的情况下,导航也意味着一个或多个存在的控件的可视化状态被更新.---例如,一些控件可能被简单的隐藏或收缩而另外的一些控件被显示后展开.类似的,导航可能意味着一个控件展示的绑定

Prism 4 文档 ---第11章 部署Prism应用程序

要成功移动Prism应用到生产中,需要对部署计划为应用程序的设计过程的一部分.本章介绍了注意事项和你需要采取的准备以部署应用程序,以及你要在用户手中获得部署程序所需要采取的行动. Silverlight和WPF有两个不同的承载环境,所以部署考虑的内容就不同了,这依赖于是否你在构建一个Silverlight Prism应用程序还是一个WPF Prism应用程序. 部署Silverlight Prism应用程序 Silverlight应用程序通过Http请求昨晚XAP文件从浏览器被分发.XAP文件其

Prism 文档 第三章 管理组件之间的依赖关系

                                                                      第3章:管理组件之间的依赖关系 基于Prism库的复合应用程序可能包含许多松耦合的类型和服务.他们需要提供内容和接收基于用户行为的通知.因为他们是松散耦合的,他们需要一种方式进行互动和相互沟通来提供所需的业务功能. 为了集中这些不同的块,基于Prism库的应用程序依赖于依赖注入容器.依赖注入容器通过提供设施去实例化类的实例和管理他们基于容器配置的寿命来减少对

Ext JS 6学习文档–第1章–ExtJS入门指南

Ext JS 入门指南 前言 本来我是打算自己写一个系列的 ExtJS 6 学习笔记的,因为 ExtJS 6 目前的中文学习资料还很少.google 搜索资料时找到了一本国外牛人写的关于 ExtJS 6 的电子书 [Ext JS 6 By Example].这份资料在 PACKT 上卖 35.99 刀的,当然了万能的 google 还是帮我下载到了 PDF 文档.大概看了一下,讲的很详细,例子也比较简单,容易理解,现我准备利用工作之余翻译这份文档,为自己学习加深理解,也希望能帮助更多的人学习.

Ext JS 6学习文档-第3章-基础组件

基础组件 在本章中,你将学习到一些 Ext JS 基础组件的使用.同时我们会结合所学创建一个小项目.这一章我们将学习以下知识点: 熟悉基本的组件 – 按钮,文本框,日期选择器等等 表单字段的校验 菜单和工具栏 设计一个表单 计算器程序– 本章的示例项目 转载请注明出处:http://www.jeeboot.com/archives/1219.html 本章的主要目的是创建一个表单设计和一个计算器示例项目.以下图分别展示了表单设计和计算器设计. 首先,你观察下列表单设计,你会发现我们使用了大量的控

Ext JS 6学习文档–第2章–核心概念

核心概念 在下一章我们会构建一个示例项目,而在这之前,你需要学习一些在 Ext JS 中的核心概念,这有助于你更容易理解示例项目.这一章我们将学习以下知识点: 类系统,创建和扩展类 事件 Ext JS 对象的查询 容器 布局 转载请注明出处:http://www.jeeboot.com/archives/1217.html class system(类系统) Ext JS 提供了很多功能,使得它创建和处理类变得简单.以下是在 Ext JS 6 的类系统中的几大组成类: Ext Base Clas

Ext JS 6学习文档-第4章-数据包

数据包 本章探索 Ext JS 中处理数据可用的工具以及服务器和客户端之间的通信.在本章结束时将写一个调用 RESTful 服务的例子.下面是本章的内容: 模型 Schema Stores 代理 过滤和排序 做一个基于 RESTful 的小项目 转载请注明出处:http://www.jeeboot.com/archives/1222.html Model(模型) 一个模型包含字段,字段类型,校验,关联和代理.它是通过扩展 Ext.data.Model 类来定义的. 其中类型,校验,关联和代理都是

Ext JS 6学习文档-第7章-图表

使用图表 本章中将探索在 ExtJS 中使用不同类型的图表并使用一个名为费用分析的示例项目结束本章所学.以下是将要所学的内容: 图表类型 条形图 和 柱形图 图表 区域 和 折线 图表 饼图 图表 3 D 图表 费用分析 – 示例项目 转载请注明出处:http://www.jeeboot.com/archives/1229.html 图表 在第一章中提过,我说 ExtJS 是一站式的几乎能满足你对所有的 JavaScript 框架的需求.这当然还包括了图表功能. 图表类型 有三种类型的图表:笛卡