【问题标题】:Alternatives to ngSwitch on constructor.name?constructor.name 上 ngSwitch 的替代方案?
【发布时间】:2014-05-13 15:05:23
【问题描述】:

在我当前的项目中,我必须处理多种类型的Categories。每个类别都必须以不同的方式呈现,并具有不同的功能。

为了实现这一点,我创建了一个Category 工厂,它在我的模型中充当“基类”。通过这种方式,我可以扩展/覆盖 Category 行为(例如,通过定义包含子类别的 MultiCategory)。

当我尝试让每个类别类型以不同方式呈现时,问题就出现了:为此,我定义了一个指令:

<div ng-repeat="category in data.categories" category="category"></div>

在我的设计中,该指令将打开category.constructor.name 来决定如何呈现自己:

<div class="container" ng-switch="category.constructor.name">
    <div ng-switch-when="MultiCategory"></div>
    ....
</div>

但是,当我尝试这样做时,AngularJS 向我抛出了一个错误,因为它不允许 constructor.name 表达式。 (与安全有关)

我通过实现一个函数找到了解决方法

Category.prototype.getType = function() {
    return this.constructor.name;
}

然后开关变成:

...ng-switch="category.getType()"...

查看jsfiddle 中的示例。

到目前为止,它工作正常,但我对这种方法不太满意。它要求我污染Category.prototype,如果使用constructor.name存在安全问题,我想解决它们。

所以我的问题是:谁能想出更好的方法

编辑:

评论/答案集中在 ngSwitch 的使用上,但这不是这个问题提出的问题。使用

我仍然会遇到同样的问题

ng-if="category.constructor.name"

重点是:确定不需要恢复到constructor.name 的模型对象类型的最佳方法是什么?我真的需要用@987654336 污染我的模型吗? @属性还是getType方法?

【问题讨论】:

  • 不同类型的渲染方式有何不同?您是否考虑过使用 ng-show 根据您从扩展类型中寻找的属性有条件地显示一个大型模板的片段?
  • @AndrewChurch 这不是重点,我仍然需要以某种方式检查类别的类型。我改进了问题,请参阅我的编辑。

标签: javascript angularjs prototypal-inheritance


【解决方案1】:

ng-switch 不是适合您的情况的最佳工具。它适用于“标签栏”之类的东西。 在你的情况下,我更喜欢

<div ng-repeat="category in data.categories">
    <ng-if="category.type == 'exampleTypeA'"></div>
    <ng-if="category.type == 'exampleTypeB'"></div>
    <ng-if="category.type == 'exampleTypeC'"></div>
    ...
</div>

【讨论】:

  • 请看我的编辑。问题的重点不是指令的选择,而是如何正确使用/设计模型。
  • 你认为它为什么会污染你的模型?
【解决方案2】:

也许它会帮助你了解我是如何做到的。我有一个名为stdClass 的基类。

在你的情况下,我会做某事。喜欢:

var Category = stdClass.extend({
    constructor:function(attrs){
       this.attrs = attrs || {};
    },
    getType:function(){ return this.type; }
});

var CategoryA = Category.extend({ type:'A' });
var CategoryB = Category.extend({ type:'B' });

现在创建新模型并将它们推送到数组中:

var collection = $scope.items = [];

var model = new CategoryA({name:'Peter'});
collection.push(model);

var model = new CategoryB({name:'Paul'});
collection.push(model);

在你看来:

<div ng-repeat="item in items">
    <div ng-if="item.type == 'A'">Category A: {{item.attrs.name}}</div>
    <div ng-if="item.type == 'B'">Category B: {{item.attrs.name}}</div>
</div>

也许这会对你有所帮助。不要犹豫,问更多... =)

【讨论】:

  • 所以你基本上为每个构造函数指定了一个类型,就像我的解决方法一样。好吧,既然显然没有更好的解决方案,我会坚持下去。这个stdClass的好方法!
  • 你不需要每个类型的构造函数。你也可以有一个“Category”-Class,构造它然后设置类型...
  • 是的,我想我的方法会因为我的静态 OO 语言背景而受到影响,javascript 原型继承的灵活性仍然让我有点害怕。
猜你喜欢
  • 2015-06-13
  • 2019-04-22
  • 2018-08-07
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多