2015-05-01 3 views
3

Я хочу передать метод из контроллера -> директива parent -> child. Я вызываю этот метод из дочернего контроллера, передавая аргументы. Он работает в родительской директиве, но я не могу передавать параметры из дочерней директивы. Ниже приведен код:Метод передачи от родительской к дочерней директиве

http://jsfiddle.net/gurukashyap/e14ff06p/6/

От родительской директивы я получаю следующий ответ в консоли: 'Ctrl метод 123'

Из директивы ребенка: Ctrl метод не определен.

Любая помощь приветствуется.

<div ng-app="MyApp"> 
    <div ng-controller="MyController"> 
     <container data-method="foo(value)"/> 
    </div> 
</div> 

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

myApp.directive('container', function() { 
    return { 
     restrict: 'E', 
     replace: 'true', 
     scope: { 
      methodToCall: '&method' 
     }, 
     template: "<div>" + 
      "<button ng-click='finish()'>Parent directive</button><child data-method=\"methodToCall(val) \"></child>" + 
      "</div>", 
     link: function (scope, element, attrs) { 
      scope.paragraphs = []; 
      scope.pushText = function() { 
       scope.paragraphs.push(scope.textToPush); 
       scope.textToPush = ""; 
      } 
      scope.finish = function() { 
       scope.methodToCall({value: '123'});         
      } 
     } 
    } 
}); 

myApp.directive('child', function() { 
    return { 
     restrict: 'E', 
     scope : { 
      methodToCall : '&method' 
     }, 
     template : '<button ng-click = "newMethod()">Child directive </button>', 
     controller : function($scope) { 
     $scope.newMethod = function() { 
      console.log('Test child '+$scope); 
      //debugger; 
     $scope.methodToCall({val : 'Testchild'}); 
    } 
    } 
    } 
}); 

myApp.controller('MyController', function ($scope, $window) { 

    $scope.foo = function (textArray) { 
     console.log('Ctrl method '+textArray) 
    }; 
}); 

ответ

4

В вашем container шаблоне вы правильно вызова methodToCall(val) функцию от объема, но вы только передавая локальную переменную val к нему (что вы правильно, опять-таки, получить от child директивы). Вам нужно, однако, передать хэш, как вы это делали из директивы child.

Таким образом, изменить часть container шаблона, который включает в себя <child> для:

<child data-method="methodToCall({value: val})"></child> 

Пожалуй, это было бы более удобным для чтения, если вы назвали внутреннюю функцию и оттуда примените -связанный функцию "&":

scope: { 
    methodToCall: '&method' 
}, 
template: '<child data-method="innerMethodToCall(val)"></child>', 
link: function(scope){ 
    scope.innerMethodToCall = function(val){ 
     scope.methodToCall({value: val}); 
    } 
} 

Ваш раздвоенный jsfiddle

+0

спасибо, что решить эту проблему. Аналогичным образом, если мы называем родительскую директиву внутри дочернего элемента рекурсивно. Нужно ли нам следовать той же процедуре. Kalava

+0

@Gurukashyap, я не совсем уверен, что вы подразумеваете под рекурсивно - вы имеете в виду, что вы можете иметь глубину N внутренних 'child'-директив? - но, да, вы могли бы что-то подобное, за исключением случаев, когда это действительно рекурсивно, вам, скорее всего, понадобится '' methodToCall ({val: val}) ", чтобы не переопределять локальную переменную из значения' val' to' '. Но если все, что вы делаете, порождает некоторые данные, есть другие способы считать –

0

У вас есть 2 номера:

У вас была опечатка в дочерней директиве, в которой вы отправляли val вместо value. Другая проблема заключается в том, что вы создали область выделения для дочерней директивы. Это нарушало целую цепочку наследования. Вместо этого вам нужно либо не использовать определение области в дочерней директиве , либо использовать scope: true.

jsfiddle - http://jsfiddle.net/2tw5mxf6/1/

обсуждение scope: {} против scope:true - https://groups.google.com/forum/#!topic/angular/7Rnd5RjdlCc

+0

честно, это похоже на неправильный способ выполнить то, что вы делаете. Хотя определение областей изоляции велико, в этом случае это не похоже на правильную реализацию. Если вы ожидаете, что пройдете несколько областей по иерархии областей, я бы рекомендовал использовать эту шину событий Angular. Затем вы можете '$ emit' данные, которые контроллер может зарегистрировать через API-интерфейс' scope. $ On'. - https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$on – jusopi

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