【问题标题】:How to implement polymorphism in sproutcore?如何在sproutcore中实现多态性?
【发布时间】:2010-11-16 23:06:13
【问题描述】:

我正在开发一个涉及类型层次结构的应用程序,并从通过继承定义每种类型的模型开始。在编写相应的控制器时,我不确定如何以干净的方式处理整个事情。我应该只为能够处理派生模型的基本类型编写一个控制器,还是应该为每个子类型编写一个控制器?应该如何设置视图控制器绑定以与不同的控制器一起使用?

【问题讨论】:

    标签: model-view-controller polymorphism sproutcore


    【解决方案1】:

    您可能想查看 SproutCore 的新实验性多态性支持:http://groups.google.com/group/sproutcore-dev/browse_thread/thread/b63483ab66333d15

    【讨论】:

      【解决方案2】:

      这里有一些关于定义子类和覆盖属性和方法的信息: http://wiki.sproutcore.com/w/page/12412971/Runtime-Objects.

      从我(有限)使用 Sproutcore 来看,我只能将 1 个视图绑定到 1 个控制器。

      因此,如果您打算使用单个视图(例如 ListView)来显示您的数据,那么我认为您只能将该视图绑定到 1 个控制器。这意味着能够处理派生模型的 1 基类型似乎是要走的路。

      【讨论】:

      • 您好,感谢您的回答。我会这样尝试。仍然想知道是否有可能以不同的方式做到这一点。顺便说一句,我正在阅读您的列表重新排序教程。这似乎很有帮助。谢谢。
      【解决方案3】:

      通常,您使用 App.store.find 调用的结果填充 ArrayController 实例的内容。 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 子类,您可能想尝试在那里使用它们。

      【讨论】:

        【解决方案4】:

        在处理模型的单个实例时,控制器应该只是对象的代理。换句话说,ObjectController 可以代理任何东西。这是我在代码中的意思:

        你有两个对象,Person 和 Student。

        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。两者都只是 ObjectController,它们可以代理任何东西。

        最后,在您的视图中,您将相关的视图元素绑定到控制器:

        ...

           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 应该是)。业务逻辑应该在模型本身上,决策逻辑应该在状态图中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-12-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多