Một bộ điều khiển AngularJS có thể gọi cái khác không?


581

Có thể có một bộ điều khiển sử dụng một bộ điều khiển khác?

Ví dụ:

Tài liệu HTML này chỉ đơn giản là in một tin nhắn được gửi bởi MessageCtrlbộ điều khiển trong messageCtrl.jstệp.

<html xmlns:ng="http://angularjs.org/">
<head>
    <meta charset="utf-8" />
    <title>Inter Controller Communication</title>
</head>
<body>
    <div ng:controller="MessageCtrl">
        <p>{{message}}</p>
    </div>

    <!-- Angular Scripts -->
    <script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
    <script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>

Tệp điều khiển chứa mã sau đây:

function MessageCtrl()
{
    this.message = function() { 
        return "The current date is: " + new Date().toString(); 
    };
}

Mà chỉ đơn giản là in ngày hiện tại;

Nếu tôi thêm một bộ điều khiển khác, DateCtrlđưa ngày ở định dạng cụ thể trở lại MessageCtrl, thì người ta sẽ làm thế nào? Khung DI dường như được quan tâm XmlHttpRequestsvà truy cập các dịch vụ.


4
Chủ đề nhóm google này, Groups.google.com/d/topic/angular/m_mn-8gnNt4/discussion , thảo luận về 5 cách mà bộ điều khiển có thể nói chuyện với nhau.
Mark Rajcok

Đã có câu trả lời tốt ở đây, vì vậy tôi chỉ muốn chỉ ra rằng trong trường hợp sử dụng cụ thể được đề cập, có lẽ bộ lọc AngularJS sẽ là giải pháp tốt hơn? Chỉ cần nghĩ rằng tôi sẽ đề cập đến nó :)
Joe Dyndale

Câu trả lời:


705

Có nhiều cách để giao tiếp giữa các bộ điều khiển.

Điều tốt nhất có lẽ là chia sẻ một dịch vụ:

function FirstController(someDataService) 
{
  // use the data service, bind to template...
  // or call methods on someDataService to send a request to server
}

function SecondController(someDataService) 
{
  // has a reference to the same instance of the service
  // so if the service updates state for example, this controller knows about it
}

Một cách khác là phát ra một sự kiện trên phạm vi:

function FirstController($scope) 
{
  $scope.$on('someEvent', function(event, args) {});
  // another controller or even directive
}

function SecondController($scope) 
{
  $scope.$emit('someEvent', args);
}

Trong cả hai trường hợp, bạn cũng có thể giao tiếp với bất kỳ chỉ thị nào.


4
Hia, Ví dụ đầu tiên sẽ yêu cầu trang web nhận thức được tất cả các dịch vụ trong ngăn xếp. Mà cảm thấy như một mùi hôi (?). Như với lần thứ hai, trang web có cần cung cấp đối số $ scope không?
BanksySan

54
Gì? Tại sao? Tất cả các bộ điều khiển được tiêm bởi Angular's DI.
Vojta

7
@JoshNoe trong 1 / bạn có hai bộ điều khiển (hoặc nhiều hơn) và cả hai đều có một dịch vụ giống hệt / chia sẻ. Sau đó, bạn có nhiều cách để giao tiếp, một số trong số đó bạn đã đề cập. Tôi sẽ quyết định dựa trên trường hợp sử dụng cụ thể của bạn. Bạn có thể đặt logic / trạng thái được chia sẻ vào dịch vụ và cả hai bộ điều khiển chỉ ủy quyền cho dịch vụ đó hoặc thậm chí xuất dịch vụ sang mẫu. Tất nhiên, dịch vụ cũng có thể kích hoạt các sự kiện ...
Vojta

137
Đến muộn thế này: các bạn có biết bạn đang tranh cãi với THE Vojta từ Google, người làm việc trên AngularJS, phải không? :)
Suman

16
Tôi thấy rõ ràng trong HTML của mình, bộ điều khiển phát ra sự kiện phải là nút con của bộ điều khiển nghe để nó hoạt động.
djangonaut

122

Xem câu đố này: http://jsfiddle.net/simpulton/XqDxG/

Đồng thời xem video sau: Giao tiếp giữa các bộ điều khiển

Html:

<div ng-controller="ControllerZero">
  <input ng-model="message" >
  <button ng-click="handleClick(message);">LOG</button>
</div>

<div ng-controller="ControllerOne">
  <input ng-model="message" >
</div>

<div ng-controller="ControllerTwo">
  <input ng-model="message" >
</div>

javascript:

var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {
  var sharedService = {};

  sharedService.message = '';

  sharedService.prepForBroadcast = function(msg) {
    this.message = msg;
    this.broadcastItem();
  };

  sharedService.broadcastItem = function() {
    $rootScope.$broadcast('handleBroadcast');
  };

  return sharedService;
});

function ControllerZero($scope, sharedService) {
  $scope.handleClick = function(msg) {
    sharedService.prepForBroadcast(msg);
  };

  $scope.$on('handleBroadcast', function() {
    $scope.message = sharedService.message;
  });        
}

function ControllerOne($scope, sharedService) {
  $scope.$on('handleBroadcast', function() {
    $scope.message = 'ONE: ' + sharedService.message;
  });        
}

function ControllerTwo($scope, sharedService) {
  $scope.$on('handleBroadcast', function() {
    $scope.message = 'TWO: ' + sharedService.message;
  });
}

ControllerZero.$inject = ['$scope', 'mySharedService'];        

ControllerOne.$inject = ['$scope', 'mySharedService'];

ControllerTwo.$inject = ['$scope', 'mySharedService'];

12
Các fiddle và video trên chia sẻ một dịch vụ. Đây là một câu đố sử dụng $ scope. $ Emit
Mark Rajcok

1
@adardesign: Tôi rất thích đọc ví dụ ngắn gọn và ý nghĩa cho các chỉ thị (cảm ơn vì câu trả lời này quá!)
sscarduzio 22/07/14

Câu trả lời tuyệt vời, tôi sử dụng myModule.service ('mySharedService', hàm ($ rootScope) {}) thay vì myModule.factory nhưng nó hoạt động không kém!
TacoEater

Thông minh. Mặc dù vậy, tôi có một câu hỏi: Tại sao bạn lại thêm một trình xử lý trong ControllerZero? $ scope. $ on ('handleBroadcast', function () {$ scope.message = sharedService.message;});
ZooZ

Video được cung cấp thực sự tuyệt vời! Tôi có vẻ như đây là những gì tôi cần để hỏi trạng thái của bộ điều khiển khác từ bộ điều khiển khác. Tuy nhiên, điều này không hoạt động bằng cách sử dụng chức năng "gọi". Nó hoạt động bằng cách sử dụng hành động "kích hoạt". Vì vậy, một cách hiệu quả, nếu một bộ điều khiển thực hiện một hành động và có một trạng thái mới, thì nó sẽ phải phát trạng thái đó và tùy thuộc vào các bộ điều khiển khác để nghe phát sóng đó và phản hồi phù hợp. Hoặc tốt hơn, thực hiện hành động trong dịch vụ chia sẻ, sau đó phát trạng thái. Xin vui lòng cho tôi biết nếu sự hiểu biết của tôi là chính xác.
tarekahf

53

Nếu bạn muốn gọi một bộ điều khiển vào một bộ điều khiển khác, có bốn phương thức khả dụng

  1. $ rootScope. $ emit () và $ rootScope. $ Broadcast ()
  2. Nếu bộ điều khiển thứ hai là con, bạn có thể sử dụng giao tiếp cha mẹ.
  3. Sử dụng dịch vụ
  4. Loại hack - với sự trợ giúp của angular.element ()

1. $ rootScope. $ Emit () và $ rootScope. $ Broadcast ()

Trình điều khiển và phạm vi của nó có thể bị phá hủy, nhưng $ rootScope vẫn còn trên ứng dụng, đó là lý do tại sao chúng tôi đang dùng $ rootScope vì $ rootScope là cha mẹ của tất cả các phạm vi.

Nếu bạn đang thực hiện giao tiếp từ cha mẹ đến con cái và thậm chí con muốn giao tiếp với anh chị em của nó, bạn có thể sử dụng $ Broadcast

Nếu bạn đang thực hiện giao tiếp từ trẻ đến cha mẹ, không có anh chị em nào tham gia thì bạn có thể sử dụng $ rootScope. $ Emit

HTML

<body ng-app="myApp">
    <div ng-controller="ParentCtrl" class="ng-scope">
      // ParentCtrl
      <div ng-controller="Sibling1" class="ng-scope">
        // Sibling first controller
      </div>
      <div ng-controller="Sibling2" class="ng-scope">
        // Sibling Second controller
        <div ng-controller="Child" class="ng-scope">
          // Child controller
        </div>
      </div>
    </div>
</body>

Mã Angularjs

 var app =  angular.module('myApp',[]);//We will use it throughout the example 
    app.controller('Child', function($rootScope) {
      $rootScope.$emit('childEmit', 'Child calling parent');
      $rootScope.$broadcast('siblingAndParent');
    });

app.controller('Sibling1', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside Sibling one');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

app.controller('Sibling2', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside Sibling two');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

app.controller('ParentCtrl', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside parent controller');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

Trong bảng điều khiển mã ở trên của $ emit 'childEmit' sẽ không gọi bên trong anh chị em ruột và Nó sẽ chỉ gọi bên trong cha mẹ, trong đó $ Broadcast cũng được gọi bên trong anh chị em và cha mẹ. Đây là nơi mà hiệu suất bắt đầu hoạt động. $ Emit là tốt hơn, nếu bạn đang sử dụng giao tiếp của con cái với cha mẹ vì nó bỏ qua một số kiểm tra bẩn.

2. Nếu Bộ điều khiển thứ hai là con, bạn có thể sử dụng giao tiếp Cha mẹ con

Đây là một trong những phương pháp tốt nhất, Nếu bạn muốn thực hiện giao tiếp cha mẹ trẻ , nơi trẻ muốn giao tiếp với cha mẹ ngay lập tức thì không cần bất kỳ loại $ Broadcast hay $ emit nào nhưng nếu bạn muốn giao tiếp từ cha mẹ với con thì bạn phải sử dụng dịch vụ hoặc $ Broadcast

Ví dụ: HTML: -

<div ng-controller="ParentCtrl">
 <div ng-controller="ChildCtrl">
 </div>
</div>

Angularjs

 app.controller('ParentCtrl', function($scope) {
   $scope.value='Its parent';
      });
  app.controller('ChildCtrl', function($scope) {
   console.log($scope.value);
  });

Bất cứ khi nào bạn đang sử dụng giao tiếp con với cha mẹ, Angularjs sẽ tìm kiếm một biến bên trong con, Nếu nó không có bên trong thì nó sẽ chọn xem các giá trị bên trong bộ điều khiển cha.

3.Sử dụng dịch vụ

AngularJS hỗ trợ các khái niệm "Phân chia mối quan tâm" bằng cách sử dụng kiến ​​trúc dịch vụ. Dịch vụ có chức năng javascript và có trách nhiệm thực hiện nhiệm vụ cụ thể only.This làm cho họ một thực thể riêng biệt mà là duy trì và kiểm chứng .Services sử dụng để tiêm sử dụng Dependency Injection mecahnism của Angularjs.

Mã Angularjs:

app.service('communicate',function(){
  this.communicateValue='Hello';
});

app.controller('ParentCtrl',function(communicate){//Dependency Injection
  console.log(communicate.communicateValue+" Parent World");
});

app.controller('ChildCtrl',function(communicate){//Dependency Injection
  console.log(communicate.communicateValue+" Child World");
});

Nó sẽ cho đầu ra Hello Child World và Hello Parent World. Theo tài liệu Angular của dịch vụ Singletons - Mỗi thành phần phụ thuộc vào một dịch vụ sẽ được tham chiếu đến một thể hiện duy nhất được tạo bởi nhà máy dịch vụ .

4.Tạo hack - với sự trợ giúp của angular.element ()

Phương thức này lấy scope () từ phần tử bởi phương thức Id / unique.angular.element () của nó trả về phần tử và scope () cung cấp biến phạm vi $ của một biến khác bằng biến $ scope của một bộ điều khiển bên trong một bộ điều khiển khác không phải là một cách làm tốt.

HTML: -

<div id='parent' ng-controller='ParentCtrl'>{{varParent}}
 <span ng-click='getValueFromChild()'>Click to get ValueFormChild</span>
 <div id='child' ng-controller='childCtrl'>{{varChild}}
   <span ng-click='getValueFromParent()'>Click to get ValueFormParent </span>
 </div>
</div>

Angularjs: -

app.controller('ParentCtrl',function($scope){
 $scope.varParent="Hello Parent";
  $scope.getValueFromChild=function(){
  var childScope=angular.element('#child').scope();
  console.log(childScope.varChild);
  }
});

app.controller('ChildCtrl',function($scope){
 $scope.varChild="Hello Child";
  $scope.getValueFromParent=function(){
  var parentScope=angular.element('#parent').scope();
  console.log(parentScope.varParent);
  }
}); 

Trong các bộ điều khiển mã ở trên đang hiển thị giá trị riêng của chúng trên Html và khi bạn nhấp vào văn bản, bạn sẽ nhận được các giá trị trong bảng điều khiển tương ứng. Nếu bạn nhấp vào nhịp của bộ điều khiển chính, trình duyệt sẽ điều khiển giá trị của con và ngược lại.


52

Dưới đây là ví dụ một trang về hai bộ điều khiển chia sẻ dữ liệu dịch vụ:

<!doctype html>
<html ng-app="project">
<head>
    <title>Angular: Service example</title>
    <script src="http://code.angularjs.org/angular-1.0.1.js"></script>
    <script>
var projectModule = angular.module('project',[]);

projectModule.factory('theService', function() {  
    return {
        thing : {
            x : 100
        }
    };
});

function FirstCtrl($scope, theService) {
    $scope.thing = theService.thing;
    $scope.name = "First Controller";
}

function SecondCtrl($scope, theService) {   
    $scope.someThing = theService.thing; 
    $scope.name = "Second Controller!";
}
    </script>
</head>
<body>  
    <div ng-controller="FirstCtrl">
        <h2>{{name}}</h2>
        <input ng-model="thing.x"/>         
    </div>

    <div ng-controller="SecondCtrl">
        <h2>{{name}}</h2>
        <input ng-model="someThing.x"/>             
    </div>
</body>
</html>

Cũng ở đây: https://gist.github.com/3595424


Và nếu theServicecập nhật thing.x, thì sự thay đổi đó sẽ tự động lan truyền đến <input> s FirstCtrlSecondCtrlphải không? Và người ta cũng có thể thay đổi thing.xtrực tiếp thông qua bất kỳ một trong hai <input> s (phải không?).
KajMagnus

4
Đúng. Tất cả các dịch vụ Angular là các singletons ứng dụng, có nghĩa là chỉ có một phiên bản của Dịch vụ. Tham khảo: docs.angularjs.org/guide/dev_guide.service.creating_service
exclsr

Liên kết trong nhận xét trước đây của tôi là 404, vì vậy, đây là hướng dẫn dịch vụ, hôm nay, ghi chú rằng các dịch vụ là singletons: docs.angularjs.org/guide/service
exclsr

1
@exclsr Vâng! Xin lỗi tôi đã bỏ lỡ điều đó trước đây
CodyBugstein

3
Cho đến nay, ví dụ tốt nhất tôi từng thấy trên web. Cảm ơn bạn
Thứ bảy

33

Nếu bạn đang tìm cách phát và phát các sự kiện để chia sẻ dữ liệu hoặc chức năng gọi qua các bộ điều khiển , vui lòng xem liên kết này : và kiểm tra câu trả lời bằng cách zbynour(trả lời với số phiếu tối đa). Tôi đang trích dẫn câu trả lời của anh ấy !!!

Nếu phạm vi của FirstCtrl là cha mẹ của phạm vi secondCtrl, mã của bạn sẽ hoạt động bằng cách thay thế $ emit bằng $ Broadcast trong FirstCtrl:

function firstCtrl($scope){
    $scope.$broadcast('someEvent', [1,2,3]);
}

function secondCtrl($scope){
    $scope.$on('someEvent', function(event, mass) {console.log(mass)});
}

Trong trường hợp không có mối quan hệ cha-con giữa các phạm vi của bạn, bạn có thể đưa $ rootScope vào bộ điều khiển và phát sự kiện tới tất cả các phạm vi con (tức là secondCtrl).

function firstCtrl($rootScope){
    $rootScope.$broadcast('someEvent', [1,2,3]);
}

Cuối cùng, khi bạn cần gửi sự kiện từ trình điều khiển con đến phạm vi lên trên, bạn có thể sử dụng $ scope. $ Emit. Nếu phạm vi của FirstCtrl là cha mẹ của phạm vi secondCtrl:

function firstCtrl($scope){
    $scope.$on('someEvent', function(event, data) { console.log(data); });
}

function secondCtrl($scope){
    $scope.$emit('someEvent', [1,2,3]);
}

24

Hai câu đố nữa: (Cách tiếp cận phi dịch vụ)

1) Dành cho bộ điều khiển Parent- Child - Sử dụng $scopebộ điều khiển cha mẹ để phát / phát các sự kiện. http://jsfiddle.net/laan_sachin/jnj6y/

2) Sử dụng $rootScopetrên các bộ điều khiển không liên quan. http://jsfiddle.net/VxafF/


Lý do nào cho tất cả sự phức tạp này với các sự kiện? Tại sao không làm một cái gì đó như thế này? jsfiddle.net/jnj6y/32
Dfr

Nó phụ thuộc vào loại quan hệ cha mẹ con đúng. Nó có thể là một người thừa kế DOM, trường hợp đó các sự kiện sẽ cho phép bạn tách rời mọi thứ.
DarkKnight

17

Trên thực tế, việc sử dụng phát và phát là không hiệu quả vì sự kiện bong bóng lên xuống theo cấu trúc phân cấp phạm vi có thể dễ dàng làm suy giảm hiệu suất đóng chai cho một ứng dụng phức tạp.

Tôi sẽ đề nghị sử dụng một dịch vụ. Đây là cách gần đây tôi đã triển khai nó trong một trong các dự án của mình - https://gist.github.com/3384419 .

Ý tưởng cơ bản - đăng ký xe buýt pub-sub / event như một dịch vụ. Sau đó tiêm xe buýt sự kiện đó bất cứ khi nào bạn cần đăng ký hoặc xuất bản các sự kiện / chủ đề.


5

Tôi cũng biết cách này.

angular.element($('#__userProfile')).scope().close();

Nhưng tôi không sử dụng nó quá nhiều, vì tôi không thích sử dụng các bộ chọn jQuery trong mã góc.


câu trả lời tốt nhất Rất đơn giản và dễ dàng ... =)
zVictor

3
@zVictor, đây thực sự là một cách tiếp cận "cuối cùng". Nó hoạt động, nhưng nó vượt ra khỏi phạm vi để buộc bạn quay trở lại. Đây là sử dụng thao tác DOM để buộc thực hiện một cái gì đó thay vì thực hiện theo cách lập trình. Nó đơn giản, nó hoạt động, nhưng nó không thể mở rộng.
Brian Nô-ê

2
@BrianNoah, đúng. Bạn có thể sử dụng mã này cho các nguyên mẫu hoặc một số thử nghiệm, nhưng không sử dụng cho mã sản xuất.
Andrey Korchak

1
Đó là điều tồi tệ nhất có thể được thực hiện. Thao tác DOM trong dịch vụ và truy cập phạm vi trực tiếp.
Mattia Franchetto

3

Có một phương pháp không phụ thuộc vào dịch vụ, $broadcasthoặc $emit. Nó không phù hợp trong mọi trường hợp, nhưng nếu bạn có 2 bộ điều khiển liên quan có thể được trừu tượng hóa thành các lệnh, thì bạn có thể sử dụng requiretùy chọn trong định nghĩa chỉ thị. Đây rất có thể là cách ngModel và ngForm giao tiếp. Bạn có thể sử dụng điều này để liên lạc giữa các bộ điều khiển chỉ thị được lồng hoặc trên cùng một phần tử.

Đối với tình huống cha mẹ / con cái, việc sử dụng sẽ như sau:

<div parent-directive>
  <div inner-directive></div>
</div>

Và những điểm chính để làm cho nó hoạt động: Trên chỉ thị cha, với các phương thức được gọi, bạn nên xác định chúng trên this(không phải trên $scope):

controller: function($scope) {
  this.publicMethodOnParentDirective = function() {
    // Do something
  }
}

Trên định nghĩa chỉ thị con, bạn có thể sử dụng requiretùy chọn để bộ điều khiển chính được chuyển đến chức năng liên kết (do đó bạn có thể gọi các chức năng trên nó từ scopechỉ thị con.

require: '^parentDirective',
template: '<span ng-click="onClick()">Click on this to call parent directive</span>',
link: function link(scope, iElement, iAttrs, parentController) {
  scope.onClick = function() {
    parentController.publicMethodOnParentDirective();
  }
}

Những điều trên có thể được nhìn thấy tại http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p=preview

Một lệnh anh chị em được sử dụng tương tự, nhưng cả hai chỉ thị trên cùng một yếu tố:

<div directive1 directive2>
</div>

Được sử dụng bằng cách tạo một phương thức trên directive1:

controller: function($scope) {
  this.publicMethod = function() {
    // Do something
  }
}

Và trong directive2, điều này có thể được gọi bằng cách sử dụng requiretùy chọn dẫn đến siblingControll được truyền cho hàm liên kết:

require: 'directive1',
template: '<span ng-click="onClick()">Click on this to call sibling directive1</span>',
link: function link(scope, iElement, iAttrs, siblingController) {
  scope.onClick = function() {
    siblingController.publicMethod();
  }
}

Điều này có thể được nhìn thấy tại http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?p=preview .

Công dụng của việc này?

  • Cha mẹ: Bất kỳ trường hợp nào các yếu tố con cần phải "đăng ký" bản thân với cha mẹ. Giống như mối quan hệ giữa ngModel và ngForm. Đây có thể thêm hành vi nhất định có thể ảnh hưởng đến các mô hình. Bạn cũng có thể có một cái gì đó hoàn toàn dựa trên DOM, trong đó một phần tử cha mẹ cần quản lý vị trí của một số đứa trẻ nhất định, nói để quản lý hoặc phản ứng với việc cuộn.

  • Anh chị em: cho phép một chỉ thị để sửa đổi hành vi của nó. ngModel là trường hợp cổ điển, để thêm các trình phân tích cú pháp / xác nhận để sử dụng ngModel trên các đầu vào.


3

Tôi không biết nếu điều này vượt quá tiêu chuẩn nhưng nếu bạn có tất cả các bộ điều khiển của mình trên cùng một tệp, thì bạn có thể làm một cái gì đó như thế này:

app = angular.module('dashboardBuzzAdmin', ['ngResource', 'ui.bootstrap']);

var indicatorsCtrl;
var perdiosCtrl;
var finesCtrl;

app.controller('IndicatorsCtrl', ['$scope', '$http', function ($scope, $http) {
  indicatorsCtrl = this;
  this.updateCharts = function () {
    finesCtrl.updateChart();
    periodsCtrl.updateChart();
  };
}]);

app.controller('periodsCtrl', ['$scope', '$http', function ($scope, $http) {
  periodsCtrl = this;
  this.updateChart = function() {...}
}]);

app.controller('FinesCtrl', ['$scope', '$http', function ($scope, $http) {
  finesCtrl = this;
  this.updateChart = function() {...}
}]);

Như bạn có thể thấy các chỉ sốCtrl đang gọi các chức năng của updateChart của cả hai bộ điều khiển khác khi gọi updateCharts.


2

Bạn có thể tiêm dịch vụ '$ bộ điều khiển' trong bộ điều khiển chính (MessageCtrl) và sau đó khởi tạo / tiêm bộ điều khiển con (DateCtrl) bằng cách sử dụng:
$scope.childController = $controller('childController', { $scope: $scope.$new() });

Bây giờ bạn có thể truy cập dữ liệu từ bộ điều khiển con của mình bằng cách gọi các phương thức của nó vì đây là một dịch vụ.
Hãy cho tôi biết nếu có vấn đề.


1

Sau đây là một publish-subscribecách tiếp cận không liên quan đến Angular JS.

Tìm kiếm bộ điều khiển tham số

//Note: Multiple entities publish the same event
regionButtonClicked: function () 
{
        EM.fireEvent('onSearchParamSelectedEvent', 'region');
},

plantButtonClicked: function () 
{
        EM.fireEvent('onSearchParamSelectedEvent', 'plant');
},

Bộ điều khiển lựa chọn tìm kiếm

//Note: It subscribes for the 'onSearchParamSelectedEvent' published by the Search Param Controller
localSubscribe: function () {
        EM.on('onSearchParamSelectedEvent', this.loadChoicesView, this);

});


loadChoicesView: function (e) {

        //Get the entity name from eData attribute which was set in the event manager
        var entity = $(e.target).attr('eData');

        console.log(entity);

        currentSelectedEntity = entity;
        if (entity == 'region') {
            $('.getvalue').hide();
            this.loadRegionsView();
            this.collapseEntities();
        }
        else if (entity == 'plant') {
            $('.getvalue').hide();
            this.loadPlantsView();
            this.collapseEntities();
        }


});

Quản lý sự kiện

myBase.EventManager = {

    eventArray:new Array(),


    on: function(event, handler, exchangeId) {
        var idArray;
        if (this.eventArray[event] == null) {
            idArray = new Array();
        } else { 
            idArray = this.eventArray[event];
        }
        idArray.push(exchangeId);
        this.eventArray[event] = idArray;

        //Binding using jQuery
        $(exchangeId).bind(event, handler);
    },

    un: function(event, handler, exchangeId) {

        if (this.eventArray[event] != null) {
            var idArray = this.eventArray[event];
            idArray.pop(exchangeId);
            this.eventArray[event] = idArray;

            $(exchangeId).unbind(event, handler);
        }
    },

    fireEvent: function(event, info) {
        var ids = this.eventArray[event];

        for (idindex = 0; idindex < ids.length; idindex++) {
            if (ids[idindex]) {

                //Add attribute eData
                $(ids[idindex]).attr('eData', info);
                $(ids[idindex]).trigger(event);
            }
        }
    }
};

Toàn cầu

var EM = myBase.EventManager;

1

Trong góc 1,5, điều này có thể được thực hiện bằng cách làm như sau:

(function() {
  'use strict';

  angular
    .module('app')
    .component('parentComponent',{
      bindings: {},
      templateUrl: '/templates/products/product.html',
      controller: 'ProductCtrl as vm'
    });

  angular
    .module('app')
    .controller('ProductCtrl', ProductCtrl);

  function ProductCtrl() {
    var vm = this;
    vm.openAccordion = false;

    // Capture stuff from each of the product forms
    vm.productForms = [{}];

    vm.addNewForm = function() {
      vm.productForms.push({});
    }
  }

}());

Đây là thành phần cha mẹ. Trong phần này tôi đã tạo ra một hàm đẩy một đối tượng khác vào productFormsmảng của mình - lưu ý - đây chỉ là ví dụ của tôi, hàm này có thể là bất cứ thứ gì thực sự.

Bây giờ chúng ta có thể tạo một thành phần khác sẽ sử dụng require:

(function() {
  'use strict';

  angular
    .module('app')
    .component('childComponent', {
      bindings: {},
      require: {
        parent: '^parentComponent'
      },
      templateUrl: '/templates/products/product-form.html',
      controller: 'ProductFormCtrl as vm'
    });

  angular
    .module('app')
    .controller('ProductFormCtrl', ProductFormCtrl);

  function ProductFormCtrl() {
    var vm = this;

    // Initialization - make use of the parent controllers function
    vm.$onInit = function() {
      vm.addNewForm = vm.parent.addNewForm;
    };  
  }

}());

Ở đây, thành phần con đang tạo một tham chiếu đến hàm thành phần cha mẹ addNewFormmà sau đó có thể được liên kết với HTML và được gọi như bất kỳ hàm nào khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.