2

У меня есть вложенные директивы.AngularJS: Вложенные директивы - привязка данных ishu

Я отправляю данные с первого на второй.

Проблема в том, что я теряю привязку к основной области.

Это мой код: Plunker

(нажав на кнопку изменяет значение в основном объеме, но не в директиве)

angular.module('app', []) 
 

 
.controller('MainCtrl', function($scope) { 
 
    
 
    $scope.change = function(){ 
 
    var id = Math.floor((Math.random() * 4) + 0); 
 
    var val = Math.floor((Math.random() * 100) + 1); 
 

 
    $scope.data.items[id].id = val; 
 
    } 
 
    $scope.data = { 
 
    items: [{ 
 
     id: 1, 
 
     name: "first" 
 
    }, { 
 
     id: 2, 
 
     name: "second" 
 
    }, { 
 
     id: 3, 
 
     name: "third" 
 
    }, { 
 
     id: 4, 
 
     name: "forth" 
 
    }] 
 
    } 
 
}) 
 

 
.directive('firstDirective', function($compile) { 
 
    return { 
 

 
    replace: true, 
 
    restrict: 'A', 
 
    scope: { 
 
     data: '=' 
 
    }, 
 
    link: function(scope, element, attrs) { 
 

 
     var template = ''; 
 
     angular.forEach(scope.data, function(item, key) { 
 
     var sss = JSON.stringify(item).replace(/"/g, "'"); 
 
     var tmp = '<div>' + 
 
      '<div second-directive data="' + sss + '"></div>' + 
 
      '</div>'; 
 
      
 
      template = template + tmp; 
 

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

 
.directive('secondDirective', function() { 
 
    var comp = function(element, attrs){ 
 
     var data = JSON.parse(attrs.data.replace(/'/g, "\"")); 
 
     var template = '<div class="second-directive">' + 
 
     '<h4>Directive 2</h4>' + 
 
     'ID :' + data.id + '<br />' + 
 
     'Name : ' + data.name + 
 
     '</div>'; 
 

 
     element.replaceWith(template); 
 
    
 
    } 
 
    
 
    return { 
 

 
    replace: true, 
 
    restrict: 'A', 
 
    compile: comp 
 
    }; 
 
});
/* Put your css in here */ 
 

 
.second-directive{ 
 
    border:1px solid green; 
 
    padding:4px; 
 
    text-align:center; 
 
    width:100px; 
 
    height:auto; 
 
    overflow:hidden; 
 
    float:left; 
 
    margin:2px; 
 
}
<!DOCTYPE html> 
 
<html ng-app="app"> 
 

 
    <head> 
 
    <meta charset="utf-8" /> 
 
    <title>AngularJS Plunker</title> 
 
    <script>document.write('<base href="' + document.location + '" />');</script> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script> 
 
    <script src="app.js"></script> 
 
    </head> 
 

 
<body ng-controller="MainCtrl"> 
 
    
 
    <h2>MainCtrl</h2> 
 
    {{data}} 
 
    <BR /> 
 
<button ng-click="change()">change value</button> 
 
    <div first-directive data="data.items"> 
 
    </div> 
 
    </body> 
 

 
</html>

спасибо

Avi

ответ

2

Не знаете, зачем нужны вложенные директивы. Кажется, слишком сложно. Почему бы просто не передать объект данных в одну директиву, и любые изменения, внесенные вами в родительском контроллере, также будут обновлены в директиве.

http://plnkr.co/edit/gR3qBRmDotiUesS6DuyN?p=preview

index.html

<!DOCTYPE html> 
<html ng-app="app"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script> 
    <script src="app.js"></script> 
    </head> 

<body ng-controller="MainCtrl"> 

    <h2>MainCtrl</h2> 
    {{data}} 
    <BR /> 
<button ng-click="change()">change value</button> 
    <div first-directive data="data.items"> 
    </div> 
    </body> 

</html> 

template1.html

<div> 
    <div class="second-directive" ng-repeat="item in data"> 
    <h4>Directive</h4> 
     ID :{{ item.id }} <br /> 
     Name : {{item.name }} 
    </div> 
</div> 

app.js

angular.module('app', []) 

.controller('MainCtrl', function($scope) { 

    $scope.change = function(){ 

    var id = Math.floor((Math.random() * 4) + 0); 
    var val = Math.floor((Math.random() * 100) + 1); 

    $scope.data.items[id].id = val; 
    } 

    $scope.data = { 
    items: [{ 
     id: 1, 
     name: "first" 
    }, { 
     id: 2, 
     name: "second" 
    }, { 
     id: 3, 
     name: "third" 
    }, { 
     id: 4, 
     name: "forth" 
    }] 
    }; 

}) 

.directive('firstDirective', function() { 

    return { 

    replace: true, 
    templateUrl: 'template1.html', 
    restrict: 'A', 

    scope: { 
     data: '=' 
    }, 

    link: function(scope, element, attrs) { 


    } 

    } 

}); 

Если вам действительно нужны вложенные директивы, вам нужно будет изучить параметр require в объекте определения директивы, где вы можете указать родительский директивный контроллер, который будет введен в функцию ссылки дочерней директивы. Затем вы можете получить доступ к любым свойствам в области родительской директивы в дочерней директиве.

См: https://docs.angularjs.org/api/ng/service/ $ компилировать # ДИРЕКТИВА РАЗРЕШЕНИЯ-объект

Надежда, что помогает.

Смежные вопросы