2015-07-03 17 views
40

Tôi đang có hai chỉ thị tùy chỉnh trong ứng dụng angularJS của mình. Một hành động như cha mẹ và hành động khác như đứa trẻ. Tôi đang cố gắng truy cập phạm vi của phụ huynh trong chỉ thị trẻ em. Nhưng tôi không nhận được kết quả mong muốn.Phạm vi truy cập chỉ thị con tùy chỉnh của phụ huynh

<div ng-controller="CountryCtrl"> 
{{myName}} 
    <div ng-controller="StateCtrl"> 
     <state nameofthestate="'Tamilnadu'"> 
      <city nameofthecity="'Chennai'"></city> 
     </state> 
    </div> 
</div> 

và kịch bản của tôi trông giống như

var app = angular.module("sampleApp",[]); 
app.controller("CountryCtrl",function($scope){ 
    $scope.myName = "India"; 
}); 
app.controller("StateCtrl",function($scope){ 
}); 
app.directive("state",function(){return { 
    restrict : 'E', 
    transclude: true, 
    scope : { myName : '=nameofthestate'}, 
    template:"** {{myName}} is inside {{$parent.myName}}<br/><ng-transclude></ng-transclude>" 
}}); 
app.directive("city",function(){return { 
    restrict : 'E', 
    require:'^state', 
    scope : { myName : '=nameofthecity'}, 
    template:"**** {{myName}} is inside {{$parent.myName}} which is in {{$parent.$parent.myName }}<br/> " 
}}); 

Tương ứng JSFiddle sẵn trong https://jsbin.com/nozuri/edit?html,js,output

Kết quả mà tôi đang nhận được là

India 
** Tamilnadu is inside India 
**** Chennai is inside India which is in Tamilnadu 

và sản lượng dự kiến ​​là

India 
** Tamilnadu is inside India 
**** Chennai is inside Tamilnadu which is in India 

Có ai có thể dạy tôi điều tôi đang làm sai ở đây không?

+0

xin lỗi, nhưng fiddle của bạn không hoạt động đối với tôi. –

+1

hi http://stackoverflow.com/questions/23437113/get-property-value-from-parent-directive-within-child-directive điều này có thể giúp bạn trông giống như những gì bạn muốn làm –

+1

Bạn có thể tạo một transclude tùy chỉnh với 'transclude: 'element''. Hàm khởi tạo có sẵn trong 'liên kết: hàm (phạm vi, phần tử, attrs, Ctlr, transclude) {}' – gr3g

Trả lời

28

Chỉ thị thành phố $ parent là phạm vi được chỉ định của chỉ thị tiểu bang.

Phạm vi được chuyển đổi của chỉ thị trạng thái được kế thừa cho $ parent của chỉ thị trạng thái là bộ điều khiển do đó đó là lý do tại sao $ parent.MyName = India.

Các $ mẹ của phạm vi nhúng là trạng thái chỉ cô lập phạm vi (scope = {}) đó là lý do tại sao $ mẹ. $ Parent.MyName = Tamilnadu (Một phần của Angular 1.3 cập nhật)

enter image description here

chút chi tiết về những gì xảy ra: How to access parent scope from within a custom directive *with own scope* in AngularJS?

transclude: true - chỉ thị tạo ra một "nhúng" con phạm vi mới, mà nguyên mẫu được thừa hưởng từ cha mẹ phạm vi. Nếu chỉ thị cũng tạo ra một phạm vi cô lập, thì phạm vi phân tách và là các anh chị em ruột. Thuộc tính $ gốc của mỗi phạm vi tham chiếu cùng phạm vi gốc.

Bản cập nhật Angular v1.3: Nếu chỉ thị cũng tạo ra một phạm vi cách ly, phạm vi được chuyển đổi giờ đây là một phần tử con của phạm vi cách ly. phạm vi nhúng và cô lập không còn là anh chị em nữa. Thuộc tính $ parent của phạm vi được chuyển đổi hiện nay tham chiếu đến phạm vi cô lập.

Câu trả lời của Matthew cũng đúng cho liên lạc chỉ thị dành cho cha mẹ và con.

15

Tính năng này có phù hợp với bạn không? Chuyển thể từ this answer.

Không có cách nào đơn giản để truy cập phần tử mẹ của nội dung được nhúng, vì vậy chúng tôi đưa bộ điều khiển cha mẹ vào con để truy cập phạm vi của nó.

var app = angular.module('myApp', []); 

    app.controller("CountryCtrl",function($scope){ 
     $scope.myName = "India"; 
    }); 

    app.controller("StateCtrl",function($scope){ 
    }); 

    app.directive("state",function(){return { 
     restrict : 'E', 
     transclude: true, 
     scope : { myName : '=nameofthestate'}, 
     template:"** {{myName}} is inside {{$parent.myName}}<br/><ng-transclude></ng-transclude>", 
     controller: function ($scope) { 
     this.getName = function() { 
      return $scope.myName; 
     } 
     } 
    }}); 

    app.directive("city",function(){return { 
     restrict : 'E', 
     require:'^state', 
     scope : { myName : '=nameofthecity'}, 
     template:"**** {{myName}} is inside {{parentName}} which is in {{$parent.myName }}<br/> ", 
     link: function(scope, element, attrs, ctrl) { 
     scope.parentName = ctrl.getName(); 
     } 
    }}); 
+1

có. Nó hoạt động. Nhưng tôi chấp nhận câu trả lời của @ kwan245 vì nó giải thích những sai lầm tôi đã làm .. :) Cảm ơn Metthew –

+0

Tôi đã sử dụng cách tiếp cận này, nhưng trong trường hợp của tôi, biến giữ tên là một mảng có thể thay đổi. Có cách nào để đối phó với tình huống này vì quan điểm không cập nhật cho tôi trong trường hợp này? Tôi biết tôi có thể sử dụng đồng hồ nhưng muốn tránh điều này càng nhiều càng tốt. Tôi có ví dụ tại đây: http://stackoverflow.com/questions/42676713/sharing-data-between-child-directives/42677394 –

3

Khi AngularJS gặp transclude, nó sao chép HTML trước khi thay thế bằng nội dung mẫu hoặc nội dung mẫu.Sau đó, khi nó gặp ng-transclude, nó biên soạn nội dung được nhúng, nhưng liên kết nó với phạm vi gốc thay vì phạm vi phân tách của chỉ thị . Do đó, nội dung được nhúng chéo vẫn có quyền truy cập vào bộ điều khiển cha mẹ và nội dung của nó, trong khi HTML chỉ thị có một phạm vi bị cô lập (hoặc phạm vi mới, như trường hợp có thể).

AngularJS lên và chạy

1

Check-out sollution của chỉ thị của tôi, nó hoạt động với rất nhiều parrents. Những gì tôi đã làm là để loại bỏ transclude và yêu cầu params. Đừng bận tâm về html bẩn, chỉ xem js, đơn giản như f ..: D

CRM.directive('inputwv', function ($compile) { 
    var getTemplate = function(contentType) { 
     var template = ''; 

     switch(contentType) { 
       case '3': 
        template = '<input type="number" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px;width:100px">' 
        break; 
       case '0': 
        template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
        break; 
       case '1': 
        template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
        break; 
       case '2': 
        template = '<textarea class="materialize-textarea teal-text" type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
        break; 
       case '4': 
        template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
        break; 
       case '5': 
        template = '<input type="date" class="datepicker" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px"><script type="text/javascript">$(\'.datepicker\').pickadate({selectMonths: true, selectYears: 15});</script>' 
        break; 
       default: 
        template = '<textarea class="materialize-textarea teal-text" type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
      } 

     return template; 
} 

    var linker = function(scope, element, attrs) { 
     element.html(getTemplate(attrs.typ)).show(); 

     $compile(element.contents())(scope); 
    } 

    return { 
     restrict: "E", 
     link: linker 
    }; 
}); 
Các vấn đề liên quan