我有两个组成部分:
<cmp-one></cmp-one>
已插入DOM,而我正在使用$compile
创建<cmp-top>
。
然后在cmpTop
控制器中,我需要获取<cmp-one>
并将其插入<cmp-top>
。
插入正常,但我需要从cmpTop
访问cmpOne
控制器方法 - 并且无法弄清楚如何。
我到目前为止尝试添加require: {cmpTop: '^^'}
- 因为在插入完成之前没有父组件而无法正常工作。
那么,我怎样才能做到这一点?我的意思是 - 将一些组件插入另一个组件,并将其方法分享给添加的孩子。
更新
以下是plunker:http://plnkr.co/edit/mgwC5Mbh5qid5q5ELDdQ?p=info
因此,我需要从PanelController
。
DialogComponentController
的方法
或者,也许我做错了 - 所以请告诉我如何正确地做到这一点。
答案 0 :(得分:1)
您可以使用公共服务在它们之间进行通信(如提及的那样)。
app.controller('mainController', function($scope, menuSelection) {
$scope.menuSelection = menuSelection; // retrieve settings object from service method and bring into scope
// now whenever one sets $scope.menuSelection.selected = "object 2", it will update the value in the other controller as well (and vice-versa)
});
app.controller('secondController', function($scope, menuSelection) {
$scope.menuSelection = menuSelection; // retrieve settings object from service method and bring into scope
});
app.factory('menuSelection', function() {
var settings = {};
settings.selected = 'Object 1'; // default
return settings;
});
您可以将$scope.menuSelection.myFooFunction = ...
指向一个指令中的函数,然后从另一个指令中调用它。
答案 1 :(得分:0)
$element
.find('.panel')
.append(srcEl
.css('display', 'block')
);
您在.find
处使用类选择器,但根据documentation,angular只支持标记选择器。
组件仅控制自己的视图和数据:组件永远不应修改超出其自身范围的任何数据或DOM。通常,在AngularJS中,可以通过范围继承和监视来修改应用程序中任何位置的数据。这是实用的,但是当不清楚应用程序的哪个部分负责修改数据时,也会导致问题。 这就是组件指令使用隔离范围的原因,因此无法进行整类范围操作。
在DialogComponentController中:
$rootScope.$emit("abc");
在PanelController中:
$rootScope.$on("abc",function(){
console.log("got it");
//and do whatever you want
});
答案 2 :(得分:0)
检查此工作示例。
var app = angular.module('plunker', []);
PanelController.$inject = ['$element'];
function PanelController($element) {
var $ctrl = this;
$ctrl.showAlert = function () {
alert('Message from PanelController');
};
$ctrl.close = function () {
// $element.remove();
};
$ctrl.onShow = function () {
};
$ctrl.$onInit = $onInit;
$ctrl.$onDestroy = $onDestroy;
function $onInit() {
var srcEl = angular.element(document.querySelector($ctrl.source));
srcEl.attr('panel', '$ctrl');
$element
.find('.panel')
.append(srcEl
.css('display', 'block')
);
$ctrl.onShow();
var bodyRect = document.body.getBoundingClientRect(),
elRect = $element[0].getBoundingClientRect(),
position = {
left: '',
top: '',
right: '',
bottom: ''
};
position.top = (bodyRect.height - elRect.height) / 4; //eslint-disable-line no-magic-numbers
position.left = (bodyRect.width - elRect.width) / 2; //eslint-disable-line no-magic-numbers
$element.css('top', position.top + 'px');
$element.css('left', position.left + 'px');
}
function $onDestroy() {
}
}
function DialogComponentController() {
var $ctrl = this;
$ctrl.callPanelMethod = function () {
var scope = angular.element($('ccm-panel div')).scope();
scope.$ctrl.showAlert();
}
$ctrl.actions = {
close: function (event, button) {
event.preventDefault();
event.stopPropagation();
$ctrl.instance.hide(button);
}
};
$ctrl.$onInit = $onInit;
$ctrl.$onDestroy = $onDestroy;
$ctrl.$onChanges = function () {
};
function $onInit() {
}
function $onDestroy() {
}
}
app.component('ccmDialog', {
template: '<div style="border: 1px solid green; margin: 5px" >dialog <button ng-click="$ctrl.callPanelMethod()">click here to get alert from controll PanelController </button></div>',
controller: DialogComponentController,
bindings: {
panel: '<',
panelShown: '&'
}
});
app.component('ccmPanel', {
template: '<div>' +
'<div style="border: 1px solid red" class="panel" ng-click="$ctrl.close()">panel</div>' +
'</div>',
controller: PanelController,
bindings: {
source: '='
}
});
app.controller('MainCtrl', function ($rootScope, $scope, $compile) {
$scope.name = 'World';
$scope.open = function (source, target) {
var scope = $rootScope.$new();
scope.$ctrl = {
source: source
};
var el = $compile('<ccm-panel source="$ctrl.source" style="position: absolute;"></ccm-panel>')(scope);
angular.element(document.querySelector(target)).append(el);
}
});
<script data-require="angular.js@1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<button ng-click="open('ccm-dialog', 'body')">open dialog</button>
<ccm-dialog panel="test" style="display: none"></ccm-dialog>
</div>