I am trying to create a small app using AngularJS which consists of users and issues posted by the users respectively.
I am trying to show issues when a particular user is clicked.
I have created the following code so far:
index.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>
app.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'
}
});
})()
userissues.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>
Whenever any user is clicked, userclickCtrl function is called where i am getting the user object from localStrorage
and want to pass it to the userissues directive for the template.
Any leads would be appreciated!!!
答案 0 :(得分:1)
Not sure what you are using localStorage
for, for sharing data between the controller and the directive? why not just use window.users.. But that is bad practice too.
There are two ways I can think of to make possible Controller-Directive communication.
$on
, $broadcast
and $emit
)In the controller, use $scope.$broadcast('eventName',eventData)
to send a message to all its child scopes, and in the directive, use $scope.$on('eventName',callback)
to listen for it. The directive can also send message to the controller by using scope.$emit('eventName',eventData)
, please do some googling or refer to the official docs for more details.
If you can figure out ways to get the reference of the directive scope, use broadcast on the directive scope directly, it will be more efficient since the event will not be broadcast to irrelevant scopes.
Also, for efficiency concerns, when you use $emit
in the directive, the $on
callback in the controller should contain event.defaultPrevented = true;
, to stop the propagation of the event into irrelevant higher class scopes.
I'm not sure whether it's a good practice but it's an effective practice that I often use.
E.g.
the directive:
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>
the controller:
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>
答案 1 :(得分:1)
不知道我是否遇到了你的问题,但也许这是一个可能的解决方案。
您可以通过以下方式将问题作为参数传递给您的指令:
app.directive(&#34; userIssues&#34;,function(){
返回{
restrict: 'E',
scope: { issue: '=' },
templateUrl: 'userissues.html'
}
});
你可以像这样使用它:
<user-issues ng-repeat="issue in issues" issue="issue"></user-issues>
尝试使用此fiddle作为示例
希望这是你需要的
答案 2 :(得分:0)
我很高兴@KevinWang和@Rick帮助我找到了我想要的答案。除此之外,我还找到了一个关于理解指令范围的精彩教程,它解释并补充了@Rick的答案。我正在这里分享链接,以便进行详细的理解。
http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/