0

我已經定義了三個指令:兒童指令之間共享數據

  • 家長

    這應該在其他兩個指令之間共享變量 - 兒童一臺和兒童兩個。

  • 兒童一臺

    這包含表示搜索項的輸入字段。每當這種變化,我使用鏈接功能來更新存儲在父控制器中的變量。

    在現實世界中,我將根據這個術語進行搜索並更新數組。但爲了簡化這個例子,我只想創建一個長度爲1的新數組,我想用搜索詞填充它作爲值。

  • 兒童兩個

    這將顯示所得到的數組。

出於某種原因,這是行不通的,如果我設置數組的長度爲0,並推動價值,我必須看到在兒童兩個視圖更新(我註釋掉實現此代碼)但我想了解爲什麼設置數組值不起作用。

我明白,一個服務將是適合這裏,但這個指令可以重新使用在同一頁面上多次,所以我不想範圍頁面上每個項目的比賽。

爲什麼視圖沒有被當前使用的代碼更新?

var app = angular 
 
    .module('SampleApplication', []) 
 
    .directive('parent', function() { 
 
    return { 
 
     restrict: 'E', 
 
     transclude: true, 
 
     template: "<div ng-transclude></div>", 
 
     controller: function($scope) { 
 
     this.searchTerm = ""; 
 
     this.arrayContainingSearchTerm = [{value: ''}]; 
 
     
 
     this.updateSearchTerm = function(searchTerm) { 
 
      this.searchTerm = searchTerm; 
 
      
 
      //When this array is assigned - it doesn't get updated in the view 
 
      this.arrayContainingSearchTerm = [{value: searchTerm}]; 
 
      
 
      //This will update the view. 
 
      //this.arrayContainingSearchTerm.length = 0; 
 
      //this.arrayContainingSearchTerm.push([{value: searchTerm}]); 
 
     }; 
 
     
 
     } 
 
    } 
 
    }) 
 
    .directive('childOne', function() { 
 
    return { 
 
     restrict: 'E', 
 
     require: '^^parent', 
 
     template: "<div><h1>Child One</h1><input ng-model='searchTerm'></input></div>", 
 
     link: function(scope, element, attrs, parentController) { 
 
     scope.$watch('searchTerm', function(newValue, oldValue) { 
 
      parentController.updateSearchTerm(newValue); 
 
     }); 
 
     } 
 
    } 
 
    }) 
 
    .directive('childTwo', function() { 
 
    return { 
 
     restrict: 'E', 
 
     require: '^^parent', 
 
     template: "<div><h1>Child Two</h1><h2>Value below should be: {{searchTerm}}</h2><h2>{{arrayContainingSearchTerm}}</h2></div>", 
 
     link: function(scope, element, attrs, parentController) { 
 
     scope.searchTerm = parentController.searchTerm; 
 
     scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm; 
 
     } 
 
    } 
 
    })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script> 
 

 

 
<div ng-app="SampleApplication"> 
 
    <parent> 
 
    <child-one></child-one> 
 
    <child-two></child-two> 
 
    </parent> 
 
</div>

回答

1

兒童範圍自動繼承父母的範圍和可以指定通過$ parent /需要父控制器訪問父母的範圍,但要注意,兄弟姐妹不能[輕鬆]訪問其他範圍。因此,解決方案是更新父範圍並將父範圍更改反映回目標孩子。

你並不需要更新子範圍,因爲孩子範圍自動從父範圍繼承。而不是看searchTerm ngModel,只需在childOne指令中使用attrs.ngModel即可。

var app = angular 
 
.module('SampleApplication', []) 
 
.directive('parent', function() { 
 
    return { 
 
    restrict: 'E', 
 
    transclude: true, 
 
    template: "<div ng-transclude></div>", 
 
    controller: function($scope) { 
 
     this.searchTerm = ""; 
 
     this.arrayContainingSearchTerm = [{value: ''}]; 
 

 
     this.updateSearchTerm = function(searchTerm) { 
 
     this.searchTerm = searchTerm; 
 

 
     //When this array is assigned - it doesn't get updated in the view 
 
     this.arrayContainingSearchTerm = [{value: searchTerm}]; 
 

 
     //This will update the view. 
 
     //this.arrayContainingSearchTerm.length = 0; 
 
     //this.arrayContainingSearchTerm.push([{value: searchTerm}]); 
 
     }; 
 

 
    } 
 
    } 
 
}) 
 
.directive('childOne', function() { 
 
    return { 
 
    restrict: 'E', 
 
    require: '^^parent', 
 
    template: "<div><h1>Child One</h1><input ng-model='searchTerm'></input></div>", 
 
    link: function(scope, element, attrs, parentController) { 
 
     // Just use attrs.ngModel 
 
     parentController.updateSearchTerm(attrs.ngModel); 
 
    } 
 
    } 
 
}) 
 
.directive('childTwo', function() { 
 
    return { 
 
    restrict: 'E', 
 
    require: '^^parent', 
 
    template: "<div><h1>Child Two</h1><h2>Value below should be: {{searchTerm}}</h2><h2>{{arrayContainingSearchTerm}}</h2></div>", 
 
    link: function(scope, element, attrs, parentController) { 
 
     // Comment/remove this since the scope is automatically inherit from parent scope 
 
     //scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm; 
 
     //scope.searchTerm = parentController.searchTerm; 
 
     // scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm; 
 

 
    } 
 
    } 
 
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script> 
 

 

 
<div ng-app="SampleApplication"> 
 
    <parent> 
 
    <child-one></child-one> 
 
    <child-two></child-two> 
 
    </parent> 
 
</div>

+0

謝謝你的回答。 我無法使用parentController。$ scope語法來訪問父控制器的作用域。 另外,你的意思是分配變量到自己的鏈接功能? 您能提供一個答案片段嗎? –

+0

嗨,我已經更新了我的答案。檢查出 – digit

+0

謝謝你的回答。我不能在Transclusion中使用這個答案,因爲父範圍會丟失,但在我的情況下,跨越不重要。我重寫了我的指令,讓孩子一和孩子二硬編碼,並且指令彼此溝通沒有任何問題。 –

1

你的第二個指令是不知道你正在做之後的變化 - 你需要$watch他們:

var app = angular 
 
.module('SampleApplication', []) 
 
.directive('parent', function() { 
 
    return { 
 
    restrict: 'E', 
 
    transclude: true, 
 
    template: "<div ng-transclude></div>", 
 
    controller: function($scope) { 
 
     this.searchTerm = ""; 
 
     this.arrayContainingSearchTerm = [{value: ''}]; 
 

 
     this.updateSearchTerm = function(searchTerm) { 
 
     this.searchTerm = searchTerm; 
 

 
     //When this array is assigned - it doesn't get updated in the view 
 
     this.arrayContainingSearchTerm = [{value: searchTerm}]; 
 

 
     //This will update the view. 
 
     //this.arrayContainingSearchTerm.length = 0; 
 
     //this.arrayContainingSearchTerm.push([{value: searchTerm}]); 
 
     }; 
 

 
    } 
 
    } 
 
}) 
 
.directive('childOne', function() { 
 
    return { 
 
    restrict: 'E', 
 
    require: '^^parent', 
 
    template: "<div><h1>Child One</h1><input ng-model='searchTerm'></input></div>", 
 
    link: function(scope, element, attrs, parentController) { 
 
     scope.$watch('searchTerm', function(newValue, oldValue) { 
 
     parentController.updateSearchTerm(newValue); 
 
     }); 
 
    } 
 
    } 
 
}) 
 
.directive('childTwo', function() { 
 
    return { 
 
    restrict: 'E', 
 
    require: '^^parent', 
 
    template: "<div><h1>Child Two</h1><h2>Value below should be: {{searchTerm}}</h2><h2>{{arrayContainingSearchTerm}}</h2></div>", 
 
    link: function(scope, element, attrs, parentController) { 
 
     scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm; 
 
     scope.searchTerm = parentController.searchTerm; 
 
     scope.$watch(function() { 
 
     scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm; 
 
     }); 
 

 
    } 
 
    } 
 
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script> 
 

 

 
<div ng-app="SampleApplication"> 
 
    <parent> 
 
    <child-one></child-one> 
 
    <child-two></child-two> 
 
    </parent> 
 
</div>

+0

謝謝你的答案,那工作,但我不知道是否有辦法,我可以做到這一點沒有手錶?我可以看到我的代碼變得相當冗長,如果我有看很多的變化。 –