Angularjs包括一个不同的控制器

时间:2013-01-22 12:18:29

标签: angularjs

我希望有一个元素,我可以使用自己的控制器获得2个视图,但一次只能有一个。 我不能使用ng-view并使用routeProvider,因为将来我需要包含更多需要根据可能的操作更改其内容的ng-includes。

我创建了一个小提琴http://jsfiddle.net/EvHyT/29/

所以我使用了ng-include,然后我从主控制器为它设置了src。那时我想使用控制器1或控制器2.

function MainCtrl($rootScope, $scope, navService){
$scope.template = {};

$scope.loadCtrl1=function(param){
    navService.loadCtrl1(param);
}

$scope.loadCtrl2=function(param){
    navService.loadCtrl2(param);
}

$rootScope.$on('loadCtrl1', function(e, args){
    $scope.template = {'url': 'temp1'};
});

$rootScope.$on('loadCtrl2', function(e, args){
     $scope.template = {'url': 'temp2'};       
});
}

我使用服务进行通信,因为我想在子控制器中移动负载控制器功能。

var myApp = angular.module('myApp',[]);


myApp.factory('navService', function($rootScope) {
return {
     loadCtrl1:function(param){
        $rootScope.$broadcast('loadCtrl1', {'id':param});   
    },

    loadCtrl2:function(param){
        $rootScope.$broadcast('loadCtrl2', {'id':param});
    }
};
});

我知道这个解决方案很糟糕,因为当插入不同的模板时尚未创建控制器,因此我的事件监听器不会触发。我也可以销毁控制器的先前实例,因为在两个控制器之间切换会使我的事件多次触发。

function Child1Ctrl($scope, $rootScope){
 $rootScope.$on('loadCtrl1', function(e, args){
   alert(args.id);
});
}

function Child2Ctrl($scope, $rootScope){

$rootScope.$on('loadCtrl2', function(e, args){
      alert(args.id);
});
}

1 个答案:

答案 0 :(得分:2)

您不需要广播(也不应该广播)来实现这一目标。 根据我的经验,如果你在rootScope上播放,你可能工作太辛苦了。

加载模板的简单方法与您正在执行的操作非常相似:

my.NavService = function() {
  this.template = 'index.html';
  this.param = null;
};
my.NavService.prototype.setTemplate(t, p) {
  this.template = t;
  this.param = p;
};

my.ctrl = function($scope, nav) {
   $scope.nav = nav;
   $scope.load = function(t, p) {
     nav.setTemplate(t, p);
   };
};

my.ctrl1 = function($scope, nav) {
  $scope.param = nav.param;
};

my.ctrl2 = function($scope, nav) {
  $scope.param = nav.param;
};

module.
  service('nav', my.NavService).
  controller('mainCtrl', my.ctrl).
  controller('ctrl1', my.ctrl1).
  controller('ctrl2', my.ctrl2);
<script type="text/ng-template" id="temp1.html">
  <div ng-controller="ctrl1">Foo {{param}}.</div>
</script>
<script type="text/ng-template" id="temp2.html">
  <div ng-controller="ctrl2">Bar {{param}}.</div>
</script>

<div ng-controller="mainCtrl">
  <a ng-click="load('temp1.html', 16)">Load 1</a>
  <a ng-click="load('temp2.html', 32)">Load 2</a>
  <div ng-include src="nav.template"></div>
</div>

这样的设置对你来说会更好。

或者,您应该考虑使用ng-switch选择性地显示元素。与ng-show / hide不同,ng-switch不会简单地向CSS添加“display:none”。它将它从DOM中删除。

有些说明:

  • 上面的例子可能不是一个有效的例子,它是对这个想法的一种表现。 这里可以看到一个工作示例:http://jsbin.com/ofakes/1它会修改您的原始代码。
  • JSFiddle在从页面脚本加载include时遇到了一些问题 标签
  • JSBin好一点。
  • 在我打破模板之前,我并没有按预期工作 进入他们自己的档案。