Быстрый NHibernate - как отобразить непосредственный подкласс?

В вашем коде есть две проблемы:

  1. с использованием асинхронного метода в теле initState(), см. здесь , подробнее

  2. Использование данных экземпляра в инициализаторе см. В здесь для подробностей.

. Ниже приведено очень простое переписывание вашего кода с минимальными исправлениями. [ 1115]

Карта данных загружается из поддельного бэкэнда, обновляется внутри PageOne и выводится на консоль в PageTwo обратного вызова onTap.

Обратите внимание, что я изменил переменную экземпляра Data на data, чтобы соответствовать рекомендациям Effective Dart .

Обратите внимание, что суть неправильно обращается к синхронизации серверной службы с общими предпочтениями: это то, что, вероятно, следует учитывать в конечном продукте.

Я только что прокомментировал, что необходимо для того, чтобы ваш код работал: если сложность вашей системы и отношения с внешним API начинают расти, возможно, стоит рассмотреть архитектуру Bloc.

import 'package:flutter/material.dart';

void main() => runApp(new MainApp());

// Mock up of an async backend service
Future> getData() async {
  return Future.delayed(Duration(seconds: 1), () => {'prop1': 'value1'});
}

class PageOne extends StatelessWidget {
  final Map data;

  PageOne({Key key, this.data}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: const Text('update preferences'),
        onPressed: () {
          data['prop2'] = 'value2';
        },
      ),
    );
  }
}

class PageTwo extends StatelessWidget {

  final Map data;

  PageTwo({Key key, this.data}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: const Text('Got It!'),
        onPressed: () {
          print("data is now: [$data]");
        },
      ),
    );
  }
}

class MainApp extends StatefulWidget {
  @override
  _MainAppState createState() => _MainAppState();
}

class _MainAppState extends State {
  //Map Data;
  Map data;

  /*
  StartFunc() async {
    Data = await getData();
    setState(() {});
  }
  */

  @override
  void initState() {
    //StartFunc();
    super.initState();
    getData().then((values) {
      setState(() {
        data = values;
      });
    });
  }

  /*
  PageOne(data:data) is an invalid value for an initializer:
   there is no way to access this at this point.
    Initializers are executed before the constructor,
    but this is only allowed to be accessed after the call
    to the super constructor.

  */
  /*
  var _pages = [
    PageOne(data:data),
    PageTwo(),
  ];
  */

  Widget getPage(int index) {
    if (index == 0) {
      return PageOne(data:data);
    }
    if (index == 1) {
      return PageTwo(data:data);
    }
    // A fallback, in this case just PageOne
    return PageOne();
  }

  int _currentIndex = 0;

  onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    /*
    return _currentIndex == 2
        ? PageTwo()
        : Scaffold(

    I use a MaterialApp because of material widgets (RaisedButton)
    It is not mandatory, but it is mainstream in flutter

     */
    return MaterialApp(
        title: 'My App',
        home: Scaffold(
          appBar: AppBar(title: Text("My App Bar")),
          body: getPage(_currentIndex),
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            items: [
              BottomNavigationBarItem(
                  icon: Icon(Icons.first_page), title: Text('')),
              BottomNavigationBarItem(
                  icon: Icon(Icons.last_page), title: Text('')),
            ],
            onTap: onTabTapped,
            currentIndex: _currentIndex,
          ),
        ));
  }
}

7
задан Nathan 17 November 2008 в 21:24
поделиться

2 ответа

Я не уверен, что понимаю то, под чем Вы подразумеваете, "отображают подкласс, непосредственный", но если Вы хотите отобразить наследование, где подклассы имеют свойства, которые не nullable, можно сделать как это в Быстром-NHibernate:

// Domain classes
public class Animal
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

public class Cat : Animal
{
    public virtual int WhiskerLength { get; set; }
    public virtual int ClawCount { get; set; }
}

public class Dog : Animal
{
    public virtual int TailWagRate { get; set; }
}



// Mapping file
public class AnimalMap : ClassMap<Animal>
{
    public AnimalMap()
    {
        Id(x => x.Id)
            .WithUnsavedValue(0)
            .GeneratedBy.Native();

        Map(x => x.Name);

        var catMap = JoinedSubClass<Cat>("CatId", sm => sm.Map(x => x.Id));

        catMap.Map(x => x.WhiskerLength)
            .CanNotBeNull();
        catMap.Map(x => x.ClawCount)
            .CanNotBeNull();

        JoinedSubClass<Dog>("DogId", sm => sm.Map(x => x.Id))
            .Map(x => x.TailWagRate)
                .CanNotBeNull();
    }
}

Так как Вы хотите, чтобы свойства подклассов были не - пустой указатель, необходимо использовать таблицу в классе (присоединенный подкласс) способ смоделировать наследование. Это вызвано тем, что таблица на иерархию требует, чтобы все свойства подкласса были nullable.

Я надеюсь, что это помогает.

/Erik

7
ответ дан 6 December 2019 в 21:21
поделиться

Синтаксис FNH мог измениться после публикации Эрика, но его пример точно соответствует цели. Вот код, который я использовал на основе сообщения Эрика для работы через FNH с двумя стратегиями подкласса FNH, о которых я знаю прямо сейчас (SubClass (закомментированный код ниже и JoinedSubClass). Кроме того, я видел другие имена, используемые для описания те же стратегии, в том числе в документации NHibernate, что немного сбивает с толку, когда это ново для вас. ( https://www.hibernate.org/hib_docs/nhibernate/html/inheritance.html ).

// Domain classes
public class Animal : Entity
{
    public virtual string Name { get; set; }
    public virtual string Unwanted { get; set; }
}

public class Cat : Animal
{
    public virtual int WhiskerLength { get; set; }
    public virtual int ClawCount { get; set; }
}

public class Dog : Animal
{
    public virtual int TailWagRate { get; set; }
}

public class Boxer : Dog
{
    public string DroolBucket { get; set; }
}

public class AnimalMapJoinedSubclassOverride : IAutoMappingOverride<Animal>
{
    public void Override(AutoMap<Animal> mapping) {
        mapping.Map(x => x.Name);

        mapping.IgnoreProperty(x => x.Unwanted);

        mapping.JoinedSubClass("CatId", CatMap.AsJoinedSubClass());
        mapping.JoinedSubClass("DogId", DogMap.AsJoinedSubClass());
        //mapping.DiscriminateSubClassesOnColumn("Type")
        //    .SubClass<Cat>("CatId", CatMap.AsSubClass())
        //    .SubClass<Dog>("CatId", DogMap.AsSubClass());
    }
}

public class CatMap
{
    public static Action<JoinedSubClassPart<Cat>> AsJoinedSubClass()
    {
        return part =>
        {
            part.Map(x => x.ClawCount).Not.Nullable();
            part.Map(x => x.WhiskerLength).Not.Nullable();
        };
    }

    public static Action<SubClassPart<Cat>> AsSubClass()
    {
        return part =>
        {
            part.Map(x => x.ClawCount);
            part.Map(x => x.WhiskerLength);
        };
    }
}

public class DogMap
{
    public static Action<JoinedSubClassPart<Dog>> AsJoinedSubClass()
    {
        return sub =>
        {
            sub.Map(x => x.TailWagRate).Not.Nullable();
        };
    }

    public static Action<SubClassPart<Dog>> AsSubClass()
    {
        return sub =>
        {
            sub.Map(x => x.TailWagRate);
        };
    }
}

public class BoxerMap
{
    public static Action<JoinedSubClassPart<Boxer>> AsJoinedSubClass()
    {
        return sub =>
        {
            sub.Map(x => x.DroolBucket);
        };
    }

    public static Action<SubClassPart<Boxer>> AsSubClass()
    {
        return sub =>
        {
            sub.Map(x => x.DroolBucket);
        };
    }
}
5
ответ дан 6 December 2019 в 21:21
поделиться
Другие вопросы по тегам:

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