angularjs 中控制器和指令之间的通信
Communication between Controller and Directive in angularjs
我正在尝试使用AngularJS创建一个小应用程序,该应用程序分别由用户和用户发布的问题组成。
我试图在单击特定用户时显示问题。
到目前为止,我已经创建了以下代码:
索引.html
<div class="container" ng-controller="issueContainer as issueTrack">
<div class="leftContainer" ng-controller="issueForm as issueformCtrl">
<issue-form></issue-form>
<user-issues ng-repeat="issue in user.issues"></user-issues>
</div>
<div class="rightContainer" ng-controller="userForm as userformCtrl">
<form name="userform" ng-submit="userform.$valid && userformCtrl.addUsers()">
<div class="form-group">
<label for="addUser">Username</label>
<input type="text" id="addUser" ng-model="userformCtrl.name" class="form-control" placeholder="Username">
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
</form>
<h3 class="usersTitle">Users</h3>
<div class="users" ng-show="issueTrack.users.length">
<div ng-repeat="user in issueTrack.users track by $index" value="{{user.username}}" ng-click="userformCtrl.userclickCtrl(user.username)">
{{user.username}}
</div>
</div>
</div>
</div>
应用.js
(function(){
var app = angular.module("Issuetracker",[]);
var users=[];
if (localStorage.getItem('users')!==null){
users = JSON.parse(localStorage.getItem("users"));
console.log(users);
}
app.controller("issueContainer", function(){
var issuetrack = this;
this.users = users;
});
app.controller("userForm", function(){
this.addUsers = function(){
users.push({'username':this.name, 'issues':[]});
this.name='';
console.log(users);
localStorage.setItem("users", JSON.stringify(users));
};
this.userclickCtrl= function(data){
var allUsers = JSON.parse(localStorage.getItem("users"));
for(var i=0;i< allUsers.length;i++){
if(allUsers[i].username == data){
var userData = allUsers[i];
break;
}
}
};
});
app.controller("issueForm", function(){
this.issue={};
this.addIssues = function(){
console.log(this.issue);
var allUsers = JSON.parse(localStorage.getItem("users"));
for(var i=0;i< allUsers.length;i++){
if(allUsers[i].username == this.issue.User){
allUsers[i].issues.push(this.issue);
break;
}
}
this.issue={};
localStorage.setItem("users", JSON.stringify(allUsers));
};
});
app.directive("userIssues", function(){
return{
restrict: 'E',
templateUrl: 'userissues.html'
}
});
app.directive("issueForm", function(){
return{
restrict: 'E',
templateUrl: 'issueform.html'
}
});
})()
用户问题.html
<div class="issues">
<div ng-repeat="issue in user.issues">
<h3>{{issue.Summary}}<span class="label label-primary" style="margin-left:2%">{{issue.Type}}</span></h3>
<p>{{issue.Description}}</p>
</div>
</div>
每当单击任何用户时,都会调用userclickCtrl函数,其中我从localStrorage
获取用户对象并希望将其传递给模板的userissues指令。
任何线索将不胜感激!!
不确定您使用localStorage
做什么,用于在控制器和指令之间共享数据? 为什么不直接使用Windows.users..但这也是不好的做法。
我能想到两种方法可以使控制器指令通信成为可能。
1.使用事件发布/订阅($on
、$broadcast
和$emit
)
在控制器中,使用 $scope.$broadcast('eventName',eventData)
将消息发送到其所有子作用域,在指令中,使用 $scope.$on('eventName',callback)
侦听该消息。该指令还可以使用 scope.$emit('eventName',eventData)
向控制器发送消息,请进行一些谷歌搜索或参考官方文档以获取更多详细信息。
如果你能想办法获取指令作用域的引用,直接在指令作用域上使用广播,会更有效,因为事件不会被广播到不相关的作用域。
此外,出于效率考虑,当您在指令中使用$emit
时,控制器中的$on
回调应包含 event.defaultPrevented = true;
,以阻止事件传播到不相关的更高类作用域。
2.通过指令属性将控制器中对象的引用(我们可以将对象称为处理程序/委托/等不太确定)传递到指令中。
我不确定这是否是一种好的做法,但这是我经常使用的有效做法。
例如
该指令:
.js:
app.directive('userIssues', function () {
return {
restrict: 'E',
templateUrl: 'templates/user-issues.html',
scope: {
delegate: '='
},
link: function (scope, element, attr) {
scope.issues = [];
scope.delegate.addIssue = function (issue) {
scope.issues.push(issue);
console.log("An issue is added to the directive !!");
};
scope.issueClicked = function (id) {
scope.delegate.issueClicked(id);
}
}
}
});
.html:
<div>
{{issues}} //I will change when notified from controller
<button ng-click="issueClicked(123)">
click me to notify controller
</button>
</div>
控制器:
.js:
app.controller('myController', function ($scope, $timeout) {
$scope.issueDirectiveDelegate = {
issueClicked: function (id) {
console.log("received message from the directive that issue with id ", id, 'is clicked');
}
};
$timeout(function(){
getMoreIssues().then(function (issue) {
$scope.issueDirectiveDelegate.addIssue(issue);
});
},1000);
});
.html:
<div> <div>blahblah</div>
<user-issues delegate="issueDirectiveDelegate"></user-issues>
</div>
不知道我是否遇到了你的问题,但也许这是一个可能的解决方案。
您可以通过以下方式将问题作为参数传递给您的指令:
app.directive("userIssues", function(){
返回{
restrict: 'E',
scope: { issue: '=' },
templateUrl: 'userissues.html'
}});
你可以像这样使用它:
<user-issues ng-repeat="issue in issues" issue="issue"></user-issues>
试试这个小提琴的例子
希望这是你需要的
我很高兴@KevinWang和@Rick帮助我找到了我正在寻找的答案。除此之外,我还发现了一个很棒的教程,关于理解指令中的范围,它解释并补充了@Rick的答案。我在这里分享链接以详细说明。
http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/
- firefox插件和dev/panel之间的通信
- 如何在两个不同的iframe HTML之间进行通信
- Angularjs事件与发布/订阅指令之间的通信
- Firefox插件SDK:在侧边栏和主脚本之间通信对象
- Ember.js:接受的子组件和父组件之间通信的最佳实践
- 如何在Windows Phone 8.1应用程序中在C#和Javascript之间传递数据或通信
- 如何在Famo.us中的两个视图(不同的js文件)之间进行通信
- 在Jquery或Javascript中获取两个范围或日期之间的通信周数
- 如何在同源选项卡之间建立通信
- 如何在 PHP 和 JS 中的并发会话之间进行通信
- 如何在两个动画画布元素之间进行通信
- 在 HTML5 和 C# Web 套接字通信之间
- angularjs 中控制器和指令之间的通信
- 歌剧扩展脚本和它们之间的通信
- 如何使用js在两个aspx页面之间进行通信
- 多个应用程序之间的通信
- Socket.IO:如何在同一服务器中的Socket.on()事件之间通信/交换数据
- chrome扩展的浏览器操作、后台脚本和内容脚本之间通信的上下文和方法
- 使用PhoneGap/Cordova时应用程序和服务器之间通信的最佳实践
- 使用AJAX在两个JavaScript文件之间通信并发送数据