机械继电器和固态继电器_角度继电器

机械继电器和固态继电器

Hi everyone, today I want to introduce you to relay-angular, an innovative and young library that I consider very stable thanks to the experience I had with Relay in creating react-relay-offline and relay-hooks libraries.

大家好,今天我想向您介绍中继角度, 一个我认为非常稳定的创新型年轻图书馆,这要归功于我在Relay上创建React-Relay-OfflineRelay-hooks库的经验。

I admit I’m not Angular’s biggest fan but creating this library allowed me to appreciate many of its aspects and realize that Relay and Angular are a great match!

我承认我不是Angular的最大粉丝,但是创建这个库使我欣赏了它的许多方面,并意识到Relay和Angular是一个很好的搭配!

Let’s start with a brief description of the three main components:

让我们从三个主要组成部分的简要说明开始:

角度的 (Angular)

构建高性能和渐进的Angular应用程序。(Build performant and progressive Angular applications.)

Angular is a platform and framework for building single-page client applications using HTML and TypeScript. Angular is written in TypeScript. It implements core and optional functionality as a set of TypeScript libraries that you import into your apps.

Angular是用于使用HTML和TypeScript构建单页客户端应用程序的平台和框架。 Angular用TypeScript编写。 它实现核心和可选功能,作为您导入到应用程序中的一组TypeScript库。

中继 (Relay)

生产就绪的GraphQL客户端。(The production-ready GraphQL client.)

Relay is a JavaScript framework for building data-driven React applications powered by GraphQL, designed from the ground up to be easy to use, extensible and, most of all, performant. Relay accomplishes this with static queries and ahead-of-time code generation.

Relay是一个JavaScript框架,用于构建由GraphQL支持的数据驱动的React应用程序,该应用程序从头开始设计,易于使用,可扩展,并且最重要的是具有高性能。 中继通过静态查询和提前代码生成来完成此任务。

Relay Modern is composed of three core modules and one babel plugin:

Relay Modern由三个核心模块和一个babel插件组成:

  • Relay Compiler: A GraphQL to GraphQL optimizing compiler, providing general utilities for transforming and optimizing queries as well as generating build artifacts. A novel feature of the compiler is that it facilitates experimentation with new GraphQL features — in the form of custom directives — by making it easy to translate code using these directives into standard, spec-compliant GraphQL.

    中继编译器:从GraphQL到GraphQL的优化编译器,提供用于转换和优化查询以及生成构建工件的通用实用程序。 编译器的一个新颖功能是通过使用自定义指令的形式将代码轻松转换为标准的,符合规范的GraphQL,从而简化了GraphQL新功能的试验。

  • Relay Runtime: A full-featured, high-performance GraphQL runtime that can be used to build higher-level client APIs. The runtime features a normalized object cache, optimized “write” and “read” operations, a generic abstraction for incrementally fetching field data (such as for pagination), garbage collection for removing unreferenced cache entries, optimistic mutations with arbitrary logic, support for building subscriptions and live queries, and more.

    中继运行时:一种功能齐全的高性能GraphQL运行时,可用于构建更高级别的客户端API。 运行时具有标准化的对象缓存,优化的“写入”和“读取”操作,用于增量获取字段数据(例如用于分页)的通用抽象,用于删除未引用的缓存条目的垃圾收集,具有任意逻辑的乐观突变,对构建的支持订阅和实时查询等。

  • React/Relay: A high-level product API that integrates the Relay Runtime with React. This is the primary public interface to Relay for most product developers, featuring APIs to fetch the data for a query or define data dependencies for reusable components (aka containers).

    React / Relay:一种高级产品API ,将Relay Runtime与React集成在一起。 对于大多数产品开发人员来说,这是Relay的主要公共接口,具有API来获取查询数据或为可重复使用的组件(也称为容器)定义数据相关性。

  • Relay Babel Plugin: a Babel plugin to convert GraphQL to runtime artifacts

    Relay Babel插件: Babel插件,可将GraphQL转换为运行时工件

Note that these modules are loosely coupled. For example, the compiler emits representations of queries in a well-defined format that the runtime consumes, such that the compiler implementation can be swapped out if desired. React/Relay relies only on the well-documented public interface of the runtime, such that the actual implementation can be swapped out (in fact, we've upgraded the classic Relay core to also implement this same API). The Relay Team hopes that this loose coupling will allow the community to explore new use-cases such as the development of specialized product APIs using the Relay runtime or integrations of the runtime with view libraries other than React.

请注意,这些模块是松散耦合的。 例如,编译器以运行时使用的定义明确的格式发出查询的表示形式,以便在需要时可以调出编译器实现。 React / Relay仅依赖于运行时记录良好的公共接口,以便可以替换实际的实现(实际上,我们已经升级了经典的Relay核心,以实现相同的API)。 Relay团队希望这种松散的耦合将使社区能够探索新的用例,例如使用Relay运行时开发专用产品API或将运行时与非React的视图库集成。

中继角度 (Relay Angular)

Angular的可量产的GraphQL客户端。(The production-ready GraphQL client for Angular.)

Now, I can confirm that this loosely coupling allowed me an easy and solid integration with Angular.

现在,我可以确认这种松散的耦合使我可以轻松,牢固地与Angular集成。

The Relay Team hopes that this loose coupling will allow the community to explore new integrations of the runtime with view libraries other than React.

中继团队希望这种松散的耦合将使社区能够使用React以外的视图库探索运行时的新集成。

This is done by creating a new core module to replace relay / react. Furthermore, it was necessary to create a new plugin as Angular does not officially support babel.

这是通过创建一个新的核心模块来代替继电器/React来完成的。 此外,由于Angular不正式支持babel,因此有必要创建一个新插件。

  • Relay Angular: A high-level product API that integrates the Relay Runtime with Angular.

    Relay Angular:将Relay Runtime和Angular集成在一起的高级产品API

  • Relay Angular Plugin: This plugin is the equivalent of the babel plugin for relay but built using the ngx-build-plus library which allows you to extend the Angular CLI’s default build behavior without ejecting. Its realization was necessary as Angular does not officially support babel.

    Relay Angular插件:此插件与babel插件等效,但使用ngx-build-plus构建,该库允许您扩展Angular CLI的默认构建行为而无需弹出。 由于Angular并未正式支持babel,因此必须意识到这一点。

Image for post
Photo by Adi Goldstein on Unsplash
Adi GoldsteinUnsplash拍摄的照片

入门(Getting started)

First, let’s install the packages we need:

首先,让我们安装所需的软件包:

  • relay-angular using yarn or npm:

    使用yarn或npm中继角:
yarn add relay-angular relay-runtime
  • relay-angular-plugin & relay-compiler using yarn or npm:

    使用yarn或npm的中继角插件和中继编译器:
yarn add relay-angular-plugin ngx-build-plus relay-compiler relay-config

1.配置编译器 (1. Configure Compiler)

配置中继(Configure relay)

Here you will find the official documentation on how to configure relay compiler.

在这里,您将找到有关如何配置中继编译器的官方文档

Example relay configuration file:

中继配置文件示例:

module.exports = {
    // ...
    // Configuration options accepted by the `relay-compiler` command-line tool,  `babel-plugin-relay` and `relay-angular-plugin`.
    src: './src',
    schema: '../server/data/schema.graphql',
    language: 'typescript',
    artifactDirectory: './src/__generated__/relay/',
};

配置ngx-build-plus(Configure ngx-build-plus)

see ngx-build-plus getting started

查看ngx-build-plus入门

  • angular.json

    angular.json

Change the builder to serve and build

更改构建者以服务和构建

{
  "build": {
    "builder": "ngx-build-plus:browser",
    ...
  },
  "serve": {
    "builder": "ngx-build-plus:dev-server",
    ...
  }
}

配置package.json(Configure package.json)

"scripts": {
    ...
    "build": "ng build --plugin relay-angular-plugin",
    "start": "ng serve --plugin relay-angular-plugin",
    "compile": "relay-compiler"
    ...
}

2.配置中继运行时(2. Configure Relay Runtime)

Here you will find the official documentation on how to configure relay runtime.

在这里,您将找到有关如何配置中继运行时的官方文档

3.将中继运行时连接到Angular (3. Connect Relay Runtime to Angular)

You connect Relay Runtime to Angular with the RelayProvider provider. The RelayProviderwraps your Angular app and places the environment in the context, which enables you to access it from anywhere.

使用RelayProvider提供程序将Relay Runtime连接到Angular。 RelayProvider包装了Angular应用程序并将环境放置在上下文中,这使您可以从任何地方访问它。

中继提供者 (RelayProvider)

RelayProvider takes an environment and sets it in the context.

RelayProvider采用environment并将其设置在上下文中。

Example of usage:

用法示例:

import { RelayProvider } from 'relay-angular';
import { Environment, Network, RecordSource, Store } from 'relay-runtime';


async function fetchQuery(operation, variables, cacheConfig, uploadables) {
    const response = await fetch('http://localhost:3000/graphql', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            query: operation.text,
            variables,
        }),
    });
    return response.json();
}
const modernEnvironment: Environment = new Environment({
    network: Network.create(fetchQuery),
    store: new Store(new RecordSource()),
});


@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  providers: [[RelayProvider(modernEnvironment)]],
  bootstrap: [AppComponent]
})
export class AppModule {
}

If you want change environment in your Angular app use:

如果要在Angular应用中更改环境,请使用:

环境语境 (EnvironmentContext)

EnvironmentContext is an extension of BehaviorSubject from rxjs.

EnvironmentContext是rxjsBehaviorSubject的扩展。

Example of usage:

用法示例:

import { Component } from '@angular/core';
import { EnvironmentContext } from 'relay-angular';
import EnvironmentError from '../relay/errorRelay';
import EnvironmentRight from '../relay/relay';


@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    constructor(private environmentContext: EnvironmentContext) {}
    // handle click button
    handleRightEnv() {
        this.environmentContext.next(EnvironmentRight);
    }
    // handle click button
    handleWrongEnv() {
        this.environmentContext.next(EnvironmentError);
    }
}

4.使用Relay作为Angular装饰器(4. Use Relay as Angular decorator)

@查询(@Query)

Decorator used to fetch a GraphQL query. It does not take an environment as an argument. Instead, it reads the environment set in the context; In addition to query (first argument) and variables (second argument), @query accepts a third argument options.

用于获取GraphQL查询的装饰器。 它不以环境为参数。 相反,它读取上下文中设置的环境。 除了query (第一个参数)和variables (第二个参数)之外, @query接受第三个参数options

Arguments:

参数:

query: The graphql tagged query. Note: relay-compiler enforces the query to be named as <FileName>Query. [Optional], if not provided, an empty props object is returned.

querygraphql标记的查询。 注意: relay-compiler强制将查询命名为<FileName>Query 。 [可选],如果未提供,则返回一个空的props对象。

variables: Object containing set of variables to pass to the GraphQL query, i.e. a mapping from variable name to value. Note: If a new set of variables is passed, the @Query will re-fetch the query.

variables:包含要传递给GraphQL查询的变量集的对象,即从变量名到值的映射。 注意:如果传递了一组新的变量,则@Query将重新获取查询。

options: see below

options:见下文

Options arguments:

选项参数:

fetchPolicy: determine whether it should use data cached in the Relay store and whether to send a network request. The options are:

fetchPolicy :确定它是否应该使用中继存储中缓存的数据以及是否发送网络请求。 选项包括:

  • store-or-network (default): Reuse data cached in the store; if the whole query is cached, skip the network request

    store-or-network (默认):重用存储在存储中的数据; 如果整个查询都已缓存,请跳过网络请求

  • store-and-network: Reuse data cached in the store; always send a network request.

    store-and-network :重用存储在存储中的数据; 始终发送网络请求。

  • network-only: Don't reuse data cached in the store; always send a network request. (This is the default behavior of Relay's existing @Query.)

    network-only :请勿重复使用存储在缓存中的数据; 始终发送网络请求。 (这是Relay现有的@Query的默认行为。)

  • store-only: Reuse data cached in the store; never send a network request.

    store-only :重复使用存储在存储中的数据; 从不发送网络请求。

fetchKey: [Optional] A fetchKey can be passed to force a refetch of the current query and variables when the component re-renders, even if the variables didn't change, or even if the component isn't remounted (similarly to how passing a different key to a React component will cause it to remount). If the fetchKey is different from the one used in the previous render, the current query and variables will be refetched.

fetchKey :[可选]可以在组件重新渲染时传递fetchKey,以强制重新查询当前查询和变量,即使变量没有变化,或者即使没有重新安装组件也是如此(类似于传递使用React组件的其他键会导致其重新安装)。 如果fetchKey与上一个渲染中使用的fetchKey不同,则将重新获取当前查询和变量。

networkCacheConfig: [Optional] Object containing cache config options for the network layer. Note: the network layer may contain an additional query response cache which will reuse network responses for identical queries. If you want to bypass this cache completely, pass {force: true} as the value for this option.

networkCacheConfig :[可选]包含网络层的缓存配置选项的对象。 注意:网络层可能包含一个附加的查询响应缓存,它将对相同的查询重用网络响应。 如果要完全绕过此缓存,请传递{force:true}作为此选项的值。

skip: [Optional] If skip is true, the query will be skipped entirely

skip :[可选]如果skip为true,则将完全跳过查询

Return Values:

返回值:

  • props: Object containing data obtained from the query; the shape of this object will match the shape of the query. If this object is not defined, it means that the data is still being fetched.

    props :包含从查询获得的数据的对象; 该对象的形状将与查询的形状匹配。 如果未定义此对象,则意味着仍在获取数据。

  • error: Error will be defined if an error has occurred while fetching the query.

    error :如果在获取查询时发生错误,则将定义错误。

  • retry: Function for reloading the data

    retry :用于重新加载数据的功能

Example of usage:

用法示例:

import { Component, Input } from '@angular/core';
import { graphql } from 'relay-runtime';
import { Query, RenderProps } from 'relay-angular';
import { todoQueryQuery } from '../../__generated__/relay/todoQueryQuery.graphql';


export const QueryApp = graphql`
    query todoQueryQuery($userId: String) {
        user(id: $userId) {
            id
            ...todoApp_user
        }
    }
`;
@Component({
    selector: 'todo-query',
    templateUrl: './todo-query.component.html',
    styleUrls: ['./todo-query.component.css'],
})
export class TodoQueryComponent {
    @Input()
    userId;


    @Query<todoQueryQuery>(function() {
        return {
            query: QueryApp,
            variables: { userId: this.userId },
        };
    })
    result: RenderProps<todoQueryQuery>;
}
<todo-app *ngIf="result && result.props && result.props.user; else loading"
  [fragmentRef]="result.props.user">
  {{result}}
 </todo-app>
 <ng-template #loading>
    <div *ngIf="!result.error; else error">
      Loading...</div>
 </ng-template>
 <ng-template #error>
    <div>
      Error {{ result.error }}
    </div>
 </ng-template>

@分段(@Fragment)

@fragmentallows components to specify their data requirements. A container does not directly fetch data, but instead declares a specification of the data needed for rendering, and then Relay will guarantee that this data is available before rendering occurs.

@fragment允许组件指定其数据要求。 容器不直接获取数据,而是声明渲染所需数据的规范,然后Relay将保证渲染发生之前该数据可用。

The decorator is automatically subscribed to updates to the fragment data: if the data for this particular User is updated anywhere in the app (e.g. via fetching new data, or mutating existing data), the component will automatically re-render with the latest updated data.

装饰器自动订阅片段数据的更新:如果此特定User的数据在应用程序中的任何位置进行了更新(例如,通过获取新数据或更改现有数据),该组件将自动使用最新的更新数据进行渲染。 。

Arguments:

参数

  • fragment: GraphQL fragment specified using a graphql template literal.

    fragment :使用graphql模板文字指定的GraphQL片段。

  • fragmentReference: The fragment reference is an opaque Relay object that Relay uses to read the data for the fragment from the store; more specifically, it contains information about which particular object instance the data should be read from. The type of the fragment reference can be imported from the generated Flow/Typescript types, from the file <fragment_name>.graphql.js, and can be used to declare the type of your Props. The name of the fragment reference type will be: <fragment_name>$key.

    fragmentReferencefragmentReference是一个不透明的Relay对象,Relay使用该对象从商店读取该片段的数据。 更具体地说,它包含有关应从中读取数据的特定对象实例的信息。 片段引用的类型可以从生成的Flow / Typescript类型,从文件<fragment_name>.graphql.js ,并且可以用来声明Props的类型。 片段引用类型的名称为: <fragment_name>$key

Return Value:

返回值:

  • data: Object that contains data which has been read out from the Relay store; the object matches the shape of specified fragment.

    data :包含已从中继存储中读取的data对象; 对象与指定片段的形状匹配。

Example of usage:

用法示例:

import { Component, Input } from '@angular/core';
import { Fragment } from 'relay-angular';
import { graphql } from 'relay-runtime';
import { todoListItem_todo$key, todoListItem_todo$data } from '../../__generated__/relay/todoListItem_todo.graphql';


const fragmentNode = graphql`
    fragment todoListItem_todo on Todo {
        complete
        id
        text
    }
`;


@Component({
    selector: 'app-todo-list-item',
    templateUrl: './todo-list-item.component.html',
    styleUrls: ['./todo-list-item.component.css'],
})
export class TodoListItemComponent {
    @Input()
    fragmentRef: todoListItem_todo$key;
    @Fragment<todoListItem_todo$key>(function() {
        return {
            fragmentNode,
            fragmentRef: this.fragmentRef,
        };
    })
    todo: todoListItem_todo$data;
}
<div class="view">
  <input class="toggle" type="checkbox" (click)="toggleTodoComplete()" [checked]="todo.complete">
  <label>{{todo.text}}</label>
  <button class="destroy" (click)="removeTodo(todo)"></button>
</div>

@Refetch(@Refetch)

You can use @refetch when you want to fetch and re-render a fragment with different data.

当您要获取并重新渲染具有不同数据的片段时,可以使用@refetch

Arguments:

参数:

They are the same as @fragment.

它们与@fragment相同

Return Value:

返回值:

data: Same object as @fragmentbut with the addition of the refetch key, function used to refetch the fragment with a potentially new set of variables.

data :与@fragment相同的对象,但添加了refetch键,该函数用于使用一组潜在的新变量来重新片段。

Example of usage:

用法示例:

import { Component, Input } from '@angular/core';
import { Refetch, RefetchDecorator } from 'relay-angular';
import { graphql } from 'relay-runtime';
import { todoListFooter_user$data } from '../../__generated__/relay/todoListFooter_user.graphql';
import { QueryApp } from '../todo-query/todo-query.component';


const fragmentNode = graphql`
    fragment todoListFooter_user on User {
        id
        userId
        completedCount
        todos(
            first: 2147483647 # max GraphQLInt
        ) @connection(key: "TodoList_todos") {
            edges {
                node {
                    id
                    complete
                }
            }
        }
        totalCount
    }
`;


@Component({
    selector: 'app-todo-list-footer',
    templateUrl: './todo-list-footer.component.html',
    styleUrls: ['./todo-list-footer.component.css'],
})
export class TodoListFooterComponent {
    @Input()
    fragmentRef: any;
    @Refetch((_this) => ({
        fragmentNode,
        fragmentRef: _this.fragmentRef,
    }))
    data: RefetchDecorator<todoListFooter_user$data>;
    // handle button click
    handleRefresh() {
        const { refetch, userId } = this.data;
        refetch(QueryApp, {
            userId,
        });
    }
}
<footer class="footer">
  <span class="todo-count">
    <strong>{{data.totalCount - data.completedCount}}</strong> 
    {{data.totalCount - data.completedCount == 1 ? 'item' : 'items'}} left
  </span>
  <button 
          class="clear-completed"
          (click)="handleRefresh($event)">
          Refresh
  </button>
</footer>

@分页(@Pagination)

You can use @Pagination to render a fragment that uses a @connection and paginate over it.

您可以使用@Pagination渲染使用@connection的片段并对其进行分页。

Arguments:

参数:

They are the same as useFragment.

它们与useFragment相同

Return Value:

返回值:

data: Same object as @fragmentbut with the addition of the keys: loadMore, hasMore, isLoading, refetchConnection

data :与@fragment相同的对象,但具有以下按键: loadMorehasMoreisLoadingrefetchConnection

有更多 (hasMore)

This function indicates whether there are more pages to fetch from the server or not.

此功能指示是否还有更多页面要从服务器获取。

hasMore: (connectionConfig?: ConnectionConfig) => boolean,

Arguments:

参数:

connectionConfig [Optional] :

connectionConfig [可选]:

  • direction: Either "forward" to indicate forward pagination using after/first, or "backward" to indicate backwards pagination using before/last. If not provided, Relay will infer the direction based on the provided @connection directive.

    direction :“ forward”使用后/首指示前向分页,或者“ backward”使用前/后指示后向分页。 如果未提供,则Relay将根据提供的@connection指令推断方向。

  • getConnectionFromProps: Function that should indicate which connection to paginate over, given the fragment props (i.e. the props corresponding to the fragmentSpec). This is necessary in most cases because the Relay can't automatically tell which connection you mean to paginate over (a container might fetch multiple fragments and connections, but can only paginate one of them). If not provided, Relay will try infer the correct connection to paginate over based on the provided @connection directive.

    getConnectionFromProps :功能应该指示分页在其上连接,给定片段的道具(即,对应于道具fragmentSpec )。 这在大多数情况下是必需的,因为中继无法自动告诉您要分页的连接(容器可能会提取多个片段和连接,但只能分页其中之一)。 如果未提供,则Relay将尝试根据提供的@connection指令推断正确的连接进行分页。

  • getFragmentVariables: Function that should return the bag of variables to use for reading out the data from the store when re-rendering the component. This function takes the previous set of variables passed to the pagination query, and the number of elements that have been fetched in total so far. Specifically, this indicates which variables to use when reading out the data from the local data store after the new pagination query has been fetched. If not specified, Relay will default to using all of the previous variables and using the total count for the count variable.

    getFragmentVariables :该函数应返回一袋变量,用于在重新呈现组件时从存储中读取数据。 此函数采用传递给分页query的上一组变量,以及到目前为止总共已获取的元素数。 具体来说,这表示在获取新的分页query之后从本地数据存储中读取数据时要使用哪些变量。 如果未指定,则Relay将默认使用所有先前的变量,并使用count变量的总计数。

  • getVariables: Function that should return the variables to pass to the pagination query when fetching it from the server, given the current props, count and cursor. You may set whatever variables here, as well as modify the defaults to use for after/first/before/last arguments.

    getVariables :在给定当前propscountcursor ,从服务器获取分页query时应返回变量以传递给分页query函数。 您可以在此处设置任何变量,也可以修改默认值以用于after / first / before / last参数。

  • query: A graphql tagged query to be used as the pagination query to fetch more data upon calling loadMore.

    query :一个graphql标记的查询,用作分页查询,以在调用loadMore时获取更多数据。

isLoading (isLoading)

This function indicates if a previous call to loadMore() is still pending. This is convenient for avoiding duplicate load calls.

此函数指示是否仍未处理对loadMore()的先前调用。 这对于避免重复的加载调用很方便。

isLoading: () => boolean,

装载更多 (loadMore)

You can call loadMore() to fetch more items from the server based on the connectionConfig provided to the container. This will return null if there are no more items to fetch, otherwise it will fetch more items and return a Disposable that can be used to cancel the fetch.

您可以调用loadMore()以根据提供给容器的connectionConfig从服务器获取更多项目。 如果没有更多要提取的项目,则将返回null,否则它将获取更多的项目并返回可用于取消提取的Disposable。

loadMore(
connectionConfig: ConnectionConfig,
pageSize: number,
callback: ?(error: ?Error) => void,
options?: RefetchOptions
): ?Disposable

Arguments:

参数:

connectionConfig [required]: Same as hasMore function

connectionConfig [必需]:与hasMore函数相同

pageSize: The number of additional items to fetch (not the total).

pageSize :要提取的其他项目数(不是总数)。

callback: Function called when the new page has been fetched. If an error occurred during refetch, this function will receive that error as an argument.

callback :获取新页面时callback函数。 如果在重新提取过程中发生错误,则此函数将接收该错误作为参数。

options: Optional object containing set of options.

options :包含选项集的可选对象。

force: If the Network Layer has been configured with a cache, this option forces a refetch even if the data for this query and variables is already available in the cache.

force :如果网络层已配置了缓存,则即使此查询和变量的数据已在缓存中,此选项也会强制进行重新提取。

refetchConnection (refetchConnection)

You can call refetchConnection to restart pagination on a connection from scratch, with optionally a completely new set of variables to pass to the pagination query. This is useful for example if you are paginating over a collection based on a userID and the userID changes, you'd want to start paginating over the new collection for the new user.

您可以调用refetchConnection从头开始在连接上重新启动分页,并可以选择使用一组全新的变量传递给分页query 。 例如,如果您要基于用户ID对集合进行分页并且用户ID发生变化,而您想开始为新用户对新集合进行分页,则这很有用。

refetchConnection:(


callback: (error: ?Error) => void,
refetchVariables: ?Variables,
) => ?Disposable,

Arguments:

参数:

connectionConfig[required]: Same as hasMore function

connectionConfig [必需]:与hasMore函数相同

totalCount: The total number of elements to fetch

totalCount :要获取的元素总数

callback: Function called when the new page has been fetched. If an error occurred during refetch, this function will receive that error as an argument.

callback :获取新页面时callback函数。 如果在重新提取过程中发生错误,则此函数将接收该错误作为参数。

refetchVariables: A potentially new bag of variables to pass to the pagination query when fetching it from the server.

refetchVariables :从服务器获取分页query时可能会传递给分页query的潜在新变量。

Example of usage:

用法示例:

import { Component, Input } from '@angular/core';
import { Pagination, PaginationDecorator } from 'relay-angular';
import { graphql } from 'relay-runtime';
import { todoListFooter_user$data } from '../../__generated__/relay/todoListFooter_user.graphql';
import { QueryApp } from '../todo-query/todo-query.component';


const fragmentSpec = graphql`
  fragment todoListFooter_user on User {
    id
    idUser
    todos(idUser: $idUser, first: $first, after: $after)
      @connection(key: "TodoList_todos", filters: ["idUser"]) {
      nextToken
      edges {
         node {
             id
             complete
         }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
`;


const connectionConfig = {
  query: QueryApp,
  getVariables: (props, paginationInfo) => ({
    first: 2,
    after: paginationInfo.cursor,
    idUser: props.idUser
  })
};


@Component({
    selector: 'app-todo-list-footer',
    templateUrl: './todo-list-footer.component.html',
    styleUrls: ['./todo-list-footer.component.css'],
})
export class TodoListFooterComponent {
    @Input()
    fragmentRef: any;
    @Pagination((_this) => ({
        fragmentNode,
        fragmentRef: _this.fragmentRef,
    }))
    data: PaginationDecorator<todoListFooter_user$data>;
    // handle button click
    handleLoadMore() {
        const { hasMore, isLoading, loadMore } = this.data;
        hasMore() && !isLoading() && loadMore(connectionConfig, 2, () => null, undefined)
    }
}
<footer class="footer">
  ...
  <button 
          class="clear-completed"
          (click)="handleLoadMore()">
          Load More
  </button>
</footer>

@RelayEnvironment(@RelayEnvironment)

Decorator used to access a Relay environment that was set by a RelayProvider:

用于访问由RelayProvider设置的Relay环境的RelayProvider

import { Component } from '@angular/core';
import { RelayEnvironment } from 'relay-angular';
import { graphql, Environment } from 'relay-runtime';


@Component({
    selector: 'todo-app',
    templateUrl: './todo-app.component.html',
    styleUrls: ['./todo-app.component.css'],
})
export class TodoAppComponent {
    @RelayEnvironment()
    environment: Environment;
}

4.变异(4. Mutation)

Use mutate function to create and execute mutations. mutate has the following signature:

使用mutate函数创建和执行变异。 mutate具有以下签名:

Arguments:

参数:

options: see below

options:见下文

Options arguments:

选项参数:

  • mutation: The graphql tagged mutation query.

    mutationgraphql标记的突变查询。

  • variables: Object containing the variables needed for the mutation. For example, if the mutation defines an $input variable, this object should contain an input key, whose shape must match the shape of the data expected by the mutation as defined by the GraphQL schema.

    variables :包含突变所需variables对象。 例如,如果变异定义了$input变量,则此对象应包含一个input键,其形状必须与GraphQL架构定义的变异所期望的数据形状匹配。

  • onCompleted: Callback function executed when the request is completed and the in-memory Relay store is updated with the updater function. Takes a response object, which is the updated response from the store, and errors, an array containing any errors from the server.

    onCompleted :当请求完成并且使用updater功能更新内存中的中继存储时执行的回调函数。 获取一个response对象,该对象是来自商店的更新后的响应,以及一个errors ,一个包含服务器中所有错误的数组。

  • onError: Callback function executed if Relay encounters an error during the request.

    onError :如果中继在请求期间遇到错误,则执行回调函数。

  • optimisticResponse: Object containing the data to optimistically update the local in-memory store, i.e. immediately, before the mutation request has completed. This object must have the same shape as the mutation's response type, as defined by the GraphQL schema. If provided, Relay will use the optimisticResponse data to update the fields on the relevant records in the local data store, before optimisticUpdater is executed. If an error occurs during the mutation request, the optimistic update will be rolled back.

    optimisticResponse :包含数据的对象,用于乐观地更新本地内存存储,即在变异请求完成之前立即更新。 该对象必须具有与GraphQL架构定义的突变的响应类型相同的形状。 如果提供,接力将使用optimisticResponse数据以更新相关记录的字段在本地数据存储,之前optimisticUpdater执行。 如果在变异请求期间发生错误,乐观更新将被回滚。

  • optimisticUpdater: Function used to optimistically update the local in-memory store, i.e. immediately, before the mutation request has completed. If an error occurs during the mutation request, the optimistic update will be rolled back. This function takes a store, which is a proxy of the in-memory Relay Store. In this function, the client defines 'how to' update the local data via the store instance. For details on how to use the store, please refer to our Relay Store API Reference. Please note: It is usually preferable to just pass an optimisticResponse option instead of an optimisticUpdater, unless you need to perform updates on the local records that are more complicated than just updating fields (e.g. deleting records or adding items to collections). If you do decide to use an optimisticUpdater, often times it can be the same function as updater.

    optimisticUpdater :用于乐观地更新本地内存存储的功能,即在变异请求完成之前立即更新。 如果在变异请求期间发生错误,乐观更新将被回滚。 此功能接受一个store ,该store是内存中的中继存储的代理。 在此功能中,客户端通过store实例定义“如何”更新本地数据。 有关如何使用store详细信息,请参阅我们的中继商店API参考请注意:通常最好只传递optimisticResponse选项而不是optimisticUpdater ,除非您需要对本地记录执行更新,而不仅仅是更新字段(例如,删除记录或向集合中添加项目)更复杂。 如果您决定使用optimisticUpdater ,通常它可以与updater具有相同的功能。

  • updater: Function used to update the local in-memory store based on the real server response from the mutation. If updater is not provided, by default, Relay will know to automatically update the fields on the records referenced in the mutation response; however, you should pass an updater if you need to make more complicated updates than just updating fields (e.g. deleting records or adding items to collections). When the server response comes back, Relay first reverts any changes introduced by optimisticUpdater or optimisticResponse and will then execute updater. This function takes a store, which is a proxy of the in-memory Relay Store. In this function, the client defines 'how to' update the local data based on the server response via the store instance. For details on how to use the store, please refer to our Relay Store API Reference.

    updater :用于根据来自突变的真实服务器响应来更新本地内存存储的功能。 如果未提供updater则默认情况下,中继将知道自动更新变异响应中引用的记录上的字段; 但是,如果您需要进行的更新不仅限于更新字段(例如,删除记录或向集合中添加项目),还应通过updater 。 当服务器响应返回时,Relay首先还原由optimisticUpdateroptimisticResponse引入的所有更改,然后执行updater 。 此功能接受一个store ,该store是内存中的中继存储的代理。 在此功能中,客户端根据服务器通过store实例的响应来定义“如何”更新本地数据。 有关如何使用store详细信息,请参阅我们的中继商店API参考

  • configs: Array containing objects describing optimisticUpdater/updater configurations. configs provides a convenient way to specify the updater behavior without having to write an updater function. See our section on Updater Configs for more details.

    configs :包含描述optimisticUpdater / updater配置的对象的数组。 configs提供了一种方便的方法来指定updater行为,而无需编写updater功能。 有关更多详细信息,请参见“更新程序配置”部分。

  • cacheConfig?: Optional object containing a set of cache configuration options

    cacheConfig? :包含一组缓存配置选项的可选对象

Example of usage:

用法示例:

import { mutate } from 'relay-angular';
import { graphql } from 'relay-runtime';


export const mutation = graphql`
    mutation changeTodoStatusMutation($input: ChangeTodoStatusInput!) {
        changeTodoStatus(input: $input) {
            todo {
                id
                complete
            }
            user {
                id
                completedCount
            }
        }
    }
`;


function commit(complete: boolean, todo: any, user: any): any {
    const input: any = {
        complete,
        userId: user.userId,
        id: todo.id,
    };
    return mutate({
        mutation,
        variables: {
            input,
        },
    });
}
export default { commit };
import { Component } from '@angular/core';
import changeTodoStatus from '../mutations/changeTodoStatus';


@Component({
    selector: 'app-todo-list-item',
    templateUrl: './todo-list-item.component.html',
    styleUrls: ['./todo-list-item.component.css'],
})
export class TodoListItemComponent {
    // handle button
    toggleTodoComplete(todo, user) {
        changeTodoStatus.commit(!todo.complete, todo, user);
    }
}
Image for post
Photo by Rocco Caruso on Unsplash
Rocco CarusoUnsplash拍摄的照片

结论:(Conclusions:)

This library simplifies the management of data fetching, offers a great developer experience and is completely open source!

该库简化了数据获取的管理,提供了出色的开发人员体验,并且是完全开源的!

If you think it can be improved please open some issues in the repository and we will discuss together!

如果您认为可以改进,请在存储库中打开一些问题,我们将一起讨论!

Well, if you’ve made it this far, you’re sure to be interested in seeing relay-angular in action!

好吧,如果您到目前为止已经做到了,那么您一定会对在实际中使用中继角感兴趣!

Try the sample project and tell me what you think.

尝试示例项目,并告诉我您的想法。

Image for post
Relay Angular in action
中继角动作

即将到来:(Cooming soon:)

翻译自: https://medium.com/@morrys/relay-for-angular-fbe8654e9132

机械继电器和固态继电器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值