AngularJS - 按条件更改控制器?

时间:2014-01-01 08:46:25

标签: javascript angularjs

我有一个简单的表格,其中的数据总结了按下的项目(通过添加)

(的 JSBIN

enter image description here

(700 = 300 + 400)

表单以ng-controller="OrderFormController"

为界

这种方法有哪些内容:

$scope.total = function(){

        var total = 0;
        angular.forEach($scope.services, function(s){
            if (s.active){
                total+= s.price;
            }
        });

        return total;
    };

一切都好。

但如果有图片,请查看顶部,有一个复选框。

选中后,我想在$scope.total

内进行完全不同的计算

让我们说,而不是添加 - 执行乘法

$scope.total = function(){

        var total = 1;
        angular.forEach($scope.services, function(s){
            if (s.active){
                total*= s.price;
            }
        });

        return total;
    };

当然我可以在方法内检查复选框是否已选中,但我不想这样做。

问题

正确的方式(我是angularjs初学者)将其绑定到不同的方法(根据checked / unchecked)是什么?

3 个答案:

答案 0 :(得分:6)

似乎没有基于某些条件选择控制器的内置方法。 ngController指令似乎不适合通过{{ }}插入名称,或传递控制器名称的字符串版本,因此似乎无法选择控制器ngController动态地基于范围中的某些条件。

我认为最灵活的解决方案是编写一个自定义指令,它接受一个字符串变量(包括由表达式返回的一个)

<div dynamic-controller="checked ? 'CheckedController' : 'UncheckedController'">
  Inside {{name}}  
</div>

然后获取控制器的名称,将其放在ng-controller属性中,然后(重新)编译元素,并在dynamic-controller返回的表达式发生更改时执行此操作。这可以按如下方式完成:

app.directive('dynamicController', function($compile) {
  return  {
    transclude: 'element',
    scope: {
      'dynamicController': '=' 
    },
    link: function(scope, element, attr, ctrl, transclude) {
      var el = null;
      scope.$watch('dynamicController',function() {
        if (el) {
          el.remove();
          el = null;
        }
        transclude(function(clone) {
          clone.attr('ng-controller', scope.dynamicController);
          clone.removeAttr('dynamic-controller');
          el = $compile(clone[0])(scope.$parent)
          element.after(el);
        });
      });
    }
  }
});

您可以在行动in this Plunker

中看到这一点

答案 1 :(得分:4)

选择控制器,但保持模板相同的一种简单方法是将模板放在外部文件中,并将其包装在ngIf中,所以:

<div ng-if="checked" ng-controller="CheckedController" ng-include="'template.html'">
</div>
<div ng-if="!checked" ng-controller="UncheckedController" ng-include="'template.html'">
</div>

可以看出in this Plunker

答案 2 :(得分:3)

根据是否选中框

,委派不同的方法
$scope.total = function() {
  if($scope.isMultiply) {
    // your multiply code
  } else {
    // non-multiply code
  }
}

您不想检查复选框是否已选中,但是没有办法解决问题。某些代码必须响应复选框的状态。这很简单,直接且易于阅读。