简体   繁体   English

如何基于条件实例化ng-controller

[英]How to instantiate ng-controller based on a condition

I asked this question but the specific question I'm asking has changed dramatically. 我问过这个问题,但我提出的具体问题发生了巨大变化。

I have a piece of code: 我有一段代码:

  <div ng-attr-controller="{{pings || 'PingsCtrl as pings' }}">
    <h1 ng-click="pings.press()">asdf</h1>
  </div>

This code is injected into two html pages. 此代码注入两个html页面。 One page already calls PingsCtrl . 一页已经调用了PingsCtrl The other doesn't. 另一个没有。 I'm really trying to keep this code DRY and I only want to have one reference of the code above. 我真的想保持这段代码DRY,我只想要一个上面的代码参考。

How can I write the code above to generate ng-controller if PingsCtrl hasn't already instantiated. 如果PingsCtrl尚未实例化,如何编写上面的代码来生成ng-controller

Here are the two html pages. 这是两个html页面。

HTML HTML

// First page
<html ng-app="coolApp">
  <div ng-controller="PingsCtrl as pings">
    <div ng-attr-controller="{{pings || 'PingsCtrl as pings' }}">
      <h1 ng-click="pings.press()">asdf</h1>
    </div>
  </div>
</html>

// Second page
<html ng-app="coolApp">
  <div ng-attr-controller="{{pings || 'PingsCtrl as pings' }}">
    <h1 ng-click="pings.press()">asdf</h1>
  </div>
</html>

Javascript is here: Javascript在这里:

angular.module('coolApp', [])

.controller('PingsCtrl', function() {
  var vm = this;

  vm.press = function() {alert(123)};
})

What's wrong and how do I fix this? 怎么了,怎么解决这个问题?

Just use a service. 只需使用服务。 It's really the intended structure for having common data and functionality between pages. 它实际上是在页面之间具有通用数据和功能的预期结构。

Part of the problem with what you were attempting is, whether or not you manage to preserve the controller, Angular has its own management that won't follow you with that, and will be refreshing components without you. 您尝试的部分问题是,无论您是否设法保留控制器,Angular都有自己的管理,不会跟随您,并且会在没有您的情况下刷新组件。 You'll run into things like a $scope that doesn't actually match the page you're looking at, and it ends up causing more problems than it's worth. 你会遇到像你看到的页面实际上没有匹配的$scope这样的东西,它最终会导致更多的问题而不是它的价值。

I do have a solution but I also echo other people's concerns about the approach. 我确实有一个解决方案,但我也回应其他人对这种方法的担忧。 You may want to have a global controller that you drop on the body for things that can happen anywhere and in most of the other controllers and just call through that. 您可能希望拥有一个全局控制器,您可以将其放在身体上,以便在任何地方和大多数其他控制器中发生这些事情,并且只需通过它进行调用。 Eg 例如

<body ng-controller="GlobalCtrl as gc">
    <h1 ng-click="gc.pingPress()"></h1>
</body>

Anyway here is what I came up with. 无论如何,这是我想出来的。

<div ng-if="pings">
    <h1 ng-click="pings.press()">asdf</h1>
</div>
<div ng-if="!pings">
    <div ng-controller="PingsCtrl as pings">
        <h1 ng-click="pings.press()">asdf</h1>
    </div>
</div>

This will work if it is dropped inside or outside of an existing PingsCtrl. 如果将其放在现有PingsCtrl的内部或外部,这将起作用。

Here is a plunker. 这是一个掠夺者。

https://plnkr.co/edit/4x0kSazcg0g0BsqPKN9C?p=preview https://plnkr.co/edit/4x0kSazcg0g0BsqPKN9C?p=preview

Please, check my solution to see how to share data between controllers 请检查我的解决方案,了解如何在控制器之间共享数据

 var app = angular.module('myApp', []); app.controller("aCtrl", function ($scope, PingList) { $scope.addPing = function() { PingList.add('Ping A'); }; }); app.controller("bCtrl", function ($scope, PingList) { $scope.addPing = function() { PingList.add('Ping B'); }; }); app.factory('PingList', function () { var pings = ['Ping1', 'Ping2']; return { add: function(ping) { pings.push(ping); }, get: function () { return pings; } }; }); app.directive('pingList', function(PingList) { return { restrict: 'EA', link: function($scope) { $scope.pings = PingList.get(); $scope.press = function(ping) { alert(ping); } }, template: '<ul><li ng-repeat="ping in pings" ng-click="press(ping)">{{ping}}</li></ul>' }; }); 
 a, li { cursor: pointer; } a { color: blue; text-decoration: underline; } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script> <div ng-app="myApp"> <div ng-controller="aCtrl" style="float: left"> <a ng-click="addPing()">click to add A ping</a> <ping-list></ping-list> </div> <div ng-controller="bCtrl" style="float: right"> <a ng-click="addPing()">click to add B ping</a> <ping-list></ping-list> </div> <div style="clear: both"></div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM