Как реализовать полиморфизм в ростке?

Я разрабатываю приложение, которое включает в себя иерархию типов и начало с определения моделей для каждого типа посредством наследования. Когда дело доходит до написания соответствующих контроллеров, я не уверен, как правильно подойти ко всему этому. Должен ли я написать только один контроллер для базового типа, который может обрабатывать производные модели, или должен быть один контроллер для каждого подтипа? Как настроить привязки контроллера вида для работы с различными контроллерами?

4 ответа

Возможно, вы захотите проверить новую экспериментальную поддержку полиморфизма в SproutCore: http://groups.google.com/group/sproutcore-dev/browse_thread/thread/b63483ab66333d15

Обычно вы заполняете содержимое экземпляров ArrayController результатами вызовов App.store.find. SC.Store#find может принимать экземпляр SC.Query, который обычно выглядит следующим образом:

MyApp.myController.set('content') = MyApp.store.find(SC.Query.local(MyApp.MyModel));

Это должно вернуть все экземпляры MyApp.MyModel, включая все экземпляры подклассов MyApp.MyModel.

Первый аргумент в SC.Query.local может быть либо подклассом SC.Record, либо строкой, ссылающейся на подкласс. Поэтому, если у вас есть промежуточные подклассы SC.Record, вы можете попробовать использовать их там.

Вот некоторая информация об определении подклассов и переопределении свойств и методов: http://wiki.sproutcore.com/w/page/12412971/Runtime-Objects.

Из моего (ограниченного) использования Sproutcore я смог привязать только 1 вид к 1 контроллеру.

Таким образом, если вы планируете использовать одно представление (например, ListView) для отображения ваших данных, то я думаю, что вы сможете привязать это представление только к одному контроллеру. Это означает, что 1 базовый тип, который способен обрабатывать производные модели, кажется, путь.

Контроллеры должны быть просто прокси для объектов при работе с отдельными экземплярами вашей модели. Другими словами, ObjectController может прокси-сервер что угодно. Вот что я имею в виду в коде:

У вас есть два объекта, человек и студент.

App.Person = SC.Object.extend({
   // person stuff here
})

App.Student = App.Person.extend({
   // student stuff here, you have have all Person things because you are extending person.
})

Затем вы хотите определить контроллеры:

App.personController = SC.ObjectController.create({
   contentBinding: 'App.path.to.person'
})

App.studentController = SC.ObjectController.create({
   contentBinding: 'App.path.to.student'
})

обратите внимание, что вы можете связать содержимое контроллера с чем-то, только если человек / ученик является результатом выбора или какого-то другого потока, где срабатывает привязка. Другими словами, если вы установите человека вручную (скажем, из диаграммы состояний в результате взаимодействия), вы все равно определите контроллер, но сделаете

App.personController.set('content', person);

Вы настраиваете контроллер по-разному в зависимости от того, является ли Person объектом верхнего уровня в вашем приложении или каким-либо промежуточным объектом, который выбирается. Кроме того, вам может понадобиться только один контроллер, у вас будут только studentController и personController, если вы одновременно воздействуете на человека и студента. Оба являются просто ObjectControllers, и они могут прокси-все.

Наконец, по вашему мнению, вы должны связать соответствующий элемент представления с контроллером:

...

   nameView: SC.LabelView.design({
      layout: {/* props */},
      valueBinding: SC.Binding.oneWay('App.personController.name')
   })

...

обратите внимание, что односторонняя привязка заключается в том, что если имя не будет изменено в представлении, если представление может изменить имя, просто выполните обычную привязку. Также обратите внимание на путь здесь. Я не привязан к

'App.personController.content.name'

Так как personController проксирует объект, вы привязываетесь к

'namespace.controller.property-on-object-controller-proxies'

Если вы вкладываете много логики в свой контроллер, вы делаете это неправильно. Контроллеры должны быть только для прокси-объектов (по крайней мере, ObjectControllers). Бизнес-логика должна быть на самих моделях, а логика принятия решений должна быть в диаграммах состояний.

Другие вопросы по тегам