Поддержка вложения ресурсов

Проблема в том, что:

SomeDelegate a = Inc;

На самом деле это не актерский состав. Это короткая форма:

SomeDelegate a = new SomeDelegate(Inc);

Поэтому нет отличных результатов. Простым решением вашей проблемы может быть это (в C # 3.0)

Func<int,int> f = i=>a(i);
4
задан Allwe 21 January 2019 в 08:00
поделиться

2 ответа

TL; DR: По умолчанию React Admin не поддерживает вложенные ресурсы, вам нужно написать собственный поставщик данных .

На этот вопрос был дан ответ по предыдущей проблеме: maremelab / реагировать-admin # 261

Подробный ответ

Поставщик данных по умолчанию в React Admin - это ra-data-simple-rest .

Как объяснено в ее документации, эта библиотека не поддерживает вложенные ресурсы, поскольку она использует только имя ресурса и идентификатор ресурса для создания URL ресурса:

Simple REST Data Provider [ 115]

Для поддержки вложенных ресурсов вы должны написать свой собственный поставщик данных.

Поддержка вложенных ресурсов - это повторяющаяся функция , запрос , но в то время основная команда не хочет справляться с такой нагрузкой. [ 1117]

Я настоятельно рекомендую собрать свои силы и написать внешнего поставщика данных и опубликовать его как ra-data-odata поставщик. Это было бы отличным дополнением, и мы будем рады помочь вам с этим внешним пакетом.

0
ответ дан Kmaschta 21 January 2019 в 08:00
поделиться

На ваш вопрос уже был дан ответ здесь , но я хотел бы рассказать вам о моем обходном пути для работы React-Admin с отношениями «многие ко многим».

Как сказано в упомянутом ответе, вы должны расширить DataProvider, чтобы он мог извлекать ресурсы отношения «многие ко многим». Однако вам нужно использовать новый глагол REST, давайте предположим, что GET_MANY_MANY_REFERENCE где-то в вашем приложении. Поскольку разные службы / API REST могут иметь разные форматы маршрутов для извлечения связанных ресурсов, я не пытался создать новый DataProvider, я знаю, что это не лучшее решение, но для коротких сроков это довольно просто.

Мое решение вдохновляло <ReferenceManyField> и создавало новый компонент <ReferenceManyManyField> для отношений «многие ко многим». Этот компонент извлекает связанные записи в componentDidMount, используя fetch API . При ответе использует данные ответа для построения на объектах, один из которых представляет собой объект с ключами, являющимися идентификаторами записей, и оценивает соответствующий объект записи, а также массив идентификаторов с идентификаторами записей. Это передается дочерним элементам вместе с другими переменными состояния, такими как page, sort, perPage, total, для обработки разбиения на страницы и упорядочения данных. Помните, что изменение порядка данных в Datagrid означает новый запрос к API. Этот компонент разделен на контроллер и представление, например <ReferencemanyField>, где контроллер извлекает данные, управляет ими и передает их дочерним элементам, а представление, которое получает данные контроллера и передает их дочерним элементам, отображает его содержимое. Это позволило мне отобразить данные отношений «многие ко многим» в Datagrid, даже если с некоторыми ограничениями это компонент для агрегирования в мой проект, и он работает только с моим текущим API, если что-то изменится, и я должен изменить поле на: но на данный момент он работает и может быть использован в моем приложении.

Детали реализации выглядят следующим образом:

//ReferenceManyManyField
export const ReferenceManyManyField = ({children, ...prop}) => {
  if(React.Children.count(children) !== 1) {
    throw new Error( '<ReferenceManyField> only accepts a single child (like <Datagrid>)' )
  }

  return <ReferenceManyManyFieldController {...props}>
    {controllerProps => (<ReferenceManyManyFieldView 
    {...props} 
    {...{children, ...controllerProps}} /> )}
  </ReferenceManyManyFieldController>

//ReferenceManyManyFieldController
class ReferenceManyManyFieldController extends Component {

  constructor(props){
    super(props)
    //State to manage sorting and pagination, <ReferecemanyField> uses some props from react-redux 
    //I discarded react-redux for simplicity/control however in the final solution react-redux might be incorporated
    this.state = {
      sort: props.sort,
      page: 1,
      perPage: props.perPage,
      total: 0
    }
  }

  componentWillMount() {
    this.fetchRelated()
  }

  //This could be a call to your custom dataProvider with a new REST verb
  fetchRelated({ record, resource, reference, showNotification, fetchStart, fetchEnd } = this.props){
    //fetchStart and fetchEnd are methods that signal an operation is being made and make active/deactivate loading indicator, dataProvider or sagas should do this
    fetchStart()
    dataProvider(GET_LIST,`${resource}/${record.id}/${reference}`,{
      sort: this.state.sort,
      pagination: {
        page: this.state.page,
        perPage: this.state.perPage
      }
    })
    .then(response => {
      const ids = []
      const data = response.data.reduce((acc, record) => {
        ids.push(record.id)
        return {...acc, [record.id]: record}
      }, {})
      this.setState({data, ids, total:response.total})
    })
    .catch(e => {
      console.error(e)
      showNotification('ra.notification.http_error')
    })
    .finally(fetchEnd)
  }

  //Set methods are here to manage pagination and ordering,
  //again <ReferenceManyField> uses react-redux to manage this
  setSort = field => {
    const order =
        this.state.sort.field === field &&
        this.state.sort.order === 'ASC'
            ? 'DESC'
            : 'ASC';
    this.setState({ sort: { field, order } }, this.fetchRelated);
  };

  setPage = page => this.setState({ page }, this.fetchRelated);

  setPerPage = perPage => this.setState({ perPage }, this.fetchRelated);

  render(){
    const { resource, reference, children, basePath } = this.props
    const { page, perPage, total } = this.state;

    //Changed basePath to be reference name so in children can nest other resources, not sure why the use of replace, maybe to maintain plurals, don't remember 
    const referenceBasePath = basePath.replace(resource, reference);

    return children({
      currentSort: this.state.sort,
      data: this.state.data,
      ids: this.state.ids,
      isLoading: typeof this.state.ids === 'undefined',
      page,
      perPage,
      referenceBasePath,
      setPage: this.setPage,
      setPerPage: this.setPerPage,
      setSort: this.setSort,
      total
    })
  }

}

ReferenceManyManyFieldController.defaultProps = {
  perPage: 25,
  sort: {field: 'id', order: 'DESC'}
}

//ReferenceManyManyFieldView
export const ReferenceManyManyFieldView = ({
  children,
  classes = {},
  className,
  currentSort,
  data,
  ids,
  isLoading,
  page,
  pagination,
  perPage,
  reference,
  referenceBasePath,
  setPerPage,
  setPage,
  setSort,
  total
}) => (
  isLoading ? 
    <LinearProgress className={classes.progress} />
  :
      <Fragment>
        {React.cloneElement(children, {
          className,
          resource: reference,
          ids,
          data,
          basePath: referenceBasePath,
          currentSort,
          setSort,
          total
        })}
        {pagination && React.cloneElement(pagination, {
          page,
          perPage,
          setPage,
          setPerPage,
          total
        })}
      </Fragment>
);

//Assuming the question example, the presentation of many-to-many relationship would be something like
const UserShow = ({...props}) => (
  <Show {...props}>
    <TabbedShowLayout>
      <Tab label='User Roles'>
        <ReferenceManyManyField source='users' reference='roles' addLabel={false} pagination={<Pagination/>}>
          <Datagrid>
            <TextField source='name'/>
            <TextField source='code'/>
          </Datagrid>
        </ReferenceManyManyField>
      </Tab>
    </TabbedShowLayout>
  </Show>
)
//Used <TabbedShowLayout> because is what I use in my project, not sure if works under <Show> or <SimpleShowLayout>, but I think it work since I use it in other contexts

Я думаю, что реализация может быть улучшена и более совместима с React-Admin. В других ссылочных полях выборка данных хранится в состоянии реакции-избыточности, в этой реализации это не так. Отношение нигде не сохраняется, кроме компонента, который не позволяет приложению работать в автономном режиме, поскольку не может извлекать данные, даже упорядочение невозможно.

0
ответ дан Mário Ferreiro 21 January 2019 в 08:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: