0

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

我创建了一个小提琴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);
});
}
4

1 回答 1

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 不会简单地将“display:none”添加到 CSS 中。它将它从 DOM 中删除。

一些注意事项:

  • 上面的例子可能不是一个有效的例子,它是一个想法的演示。可以在这里看到一个工作示例:http: //jsbin.com/ofakes/1它修改了您的原始代码。
  • JSFiddle 在从页面脚本标记加载包含时遇到了一些问题。
  • JSBin 稍微好一点。
  • 直到我将模板分解为它们自己的文件之前,我并没有真正让它按预期工作。
于 2013-01-23T00:51:06.210 回答