2016-12-04 59 views
4

我正在使用AngularJS 1.5.8。 我有「myParent」和「myChild」組件。 在我看來,我有1個父母和2個孩子在那個父母裏面。 所以我的問題是:我想在「myParent」組件的控制器中有兒童「myChild」組件的實例,並且僅給特定的子項命令makePrimary(),或者像那樣...我如何實現此操作目標?從AngularJS的父級命令一個特定的子組件

JS:

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

angular. 
module('myChild', []). 
component('myChild', { 
    template: '<div class="panel panel-default">' + 
    '<div class="panel-heading">Child</div>' + 
    '<div class="panel-body">' + 
    'Child content...' + 
    '</div>' + 
    '</div>', 
    controller: ['$scope', '$element', 
    function myChildController($scope, $element) { 

    } 
    ] 
}); 

angular. 
module('myParent', ['myChild']). 
component('myParent', { 
    template: '<div class="panel panel-default">' + 
    '<div class="panel-heading">Parent</div>' + 
    '<div class="panel-body">' + 
    '<my-child></my-child>' + 
    '<hr />' + 
    '<my-child></my-child>' + 
    '</div>' + 
    '</div>', 
    controller: ['$scope', '$element', 
    function myParentController($scope, $element) { 

    // TODO: MAKE CHILD-2 ".panel-primary" CLASS IN HERE. 
    // BUT ONLY A SPECIFIC CHILD! 

    } 
    ] 
}); 

HTML:

<div ng-app="myApp" class="container"> 
    <my-parent></my-parent> 
</div> 

的jsfiddle樣品: https://jsfiddle.net/zhc12t1a/4/

我考察像一些相關的問題:

但我找不到才達到用一個簡單的架構這個目標取之有道。

編輯

我知道有一些複雜的方法(從建築角度看),但我不想使用它們。例如:

使用$父母或

在myParentController

$scope.makeChild1Primary = function() {} 

在myParent模板:

<my-child make-primary="makeChild1Primary"></my-child> 

在myChild組件

//... 
var ctrl = this; 
ctrl.makePrimary = function() { /* MAKE PRIMARY LOGIC HERE... */ } 
//... 
,bindings: { 
makePrimary: '=' 
} 
+1

考慮使用服務共享狀態;它避免了爬行範圍的複雜性,$廣播處理程序的耗盡,並且很容易在控制器和指令中共享。 – RamblinRose

回答

4

正如在提到「 AngularJS - Access to child scope「,因此無法從父級訪問子級作用域,因爲AngularJS從子級到父級處理屬性,而不是相反。

如果你不想納克級的子元素的結合父母的財​​產或使用公共服務,你必須明確地添加兒童作用域的parent屬性,像這樣:

function myParentController($scope, $element) { 
    $scope.children = []; 
    ... 
} 

function myChildController($scope, $element) { 
    $scope.$parent.children.push($scope); 
} 

然後你可以從父訪問所有的孩子,像這樣:

$scope.children[1].isPrimary = true; 

雖然在你的HTML綁定類的面板屬性「值isPrimary」像這樣:

<div class="panel panel-default" ng-class="isPrimary ? 'panel-primary' : ''"> 

你可以找到你的例子這裏的整個實施:https://jsfiddle.net/81eesouy/7/

+0

感謝您的評論。但我不想使用$ parent。因爲未來我可以有不同的父母,所以我可能會將我的組件移到其他組件中。因此,使用$家長可能會混淆未來。所以我找到了另一種方式併發布了它。當然你的答案是正確的,但我發現的新方式似乎更適合我。 –

+1

謝謝你的回覆。這個要求有很多可能的解決方案,但是使用孩子範圍是按照您的問題要求僅給予特定孩子**的唯一方法。 – ggradnig

0

我用的子組件的綁定配置實現了這一目標。 這裏的關鍵點,變化(由父母做出)反映到孩子的約束屬性。我們必須永遠記住!因此,需作修改爲如下:

JS:

function myParentController($scope) { 
    // the variables that controls children's primary statuses 
    $scope.child1Primary = false; 
    $scope.child2Primary = false; 
} 


// component definition 
// ... 
controller: ['$scope', 
    function myChildController($scope) { 
    // This $watch is not required. I used it for only showing that the changes are reflecting dynamically. 
     $scope.$watch('$ctrl.isPrimary', function(newVal) { 
     alert("CHANGE DETECTED BY CHILD\n$ctrl.isPrimary: " + newVal); 
     }) 
    } 
    ], 
    bindings: { 
    isPrimary: '<' 
    } 
//... 

父模板:

<my-child is-primary="child1Primary"></my-child><br /> 
<my-child is-primary="child2Primary"></my-child> 

完整的jsfiddle LINK: https://jsfiddle.net/zhc12t1a/5/

每當我們改變childXPrimary變量中,$ ctrl.isPrimary變量正在改變孩子的範圍。因此,不需要像「myChild」組件中的「makePrimary」這樣的函數。

注意:ng-class用於類更改,但它是一個細節。這裏重要的事情是通信架構

1

可以使用$ emit$ broadcast event。

這是最好的清潔答案,我想,你可以嘗試的服務,但這個是我更喜歡:)

快速例如

function controllerParent($scope){ 
    $scope.emitActionClick = function(){ 
     $scope.$emit('myTestEvent',{data:"passed"})    
    } 


} 
function controllerChildX($scope){ 
    $scope.$on('myTestEvent',function(event,data){ 
     // HERE WE ARE :) 
     console.log(data); 
    } 

} 

如果您正在使用控制器回答您將需要注入$ scope或$ rootScope。 不幸的是,處理髮射和廣播事件沒有其他辦法。

+0

感謝您的回覆。確實如此,但是,在組件中使用$ emit和。$ on很難追蹤哪個組件發出哪些事件以及哪些組件捕獲該事件,我想。 –

相關問題